016.Python闭包函数以及locals和globals

一 闭包函数

内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数

1.1 闭包函数语法

def outer():
    a = 5
    def inner():
        print(a)
    return inner

对比正常的局部变量

局部变量的生命周期最短,在调用结束之后,立即释放.

def func():
    a = 5
    print(a)
func()
print(a)

执行

1.2 闭包函数的定义

def bibao():
        people = "孙仲谋"
        def caocao_say():
                print("生子当如%s" % (people))
        return caocao_say

func = bibao()
# func = caocao_say
func()

执行

[[email protected] python]# python3 test.py
生子当如孙仲谋

1.3 闭包函数的特点(升级)

  • 内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期(实际内存给它存储了这个值,暂时不释放)

示例

def grade(str1):
    def func_in(str2):
        print(str1+str2)
    return func_in

a=grade(‘小李:‘)
a(‘语文:118‘)

b=grade(‘小红:‘)
b(‘语文:109‘)
b(‘数学:98‘)

执行

[[email protected] python]# python3 test.py
小李:语文:118
小红:语文:109
小红:数学:98

示例2

def family():
        jiejie = "小红"
        meimei = "小明"
        money = 100

        def jiejie_hobby():
                nonlocal money
                money -=40
                print("姐姐%s喜欢买零食,买了辣条钱还剩下%s" % (jiejie,money))
                return money

        def meimei_hobby():
                nonlocal money
                money -= 30
                print("妹妹%s喜欢买衣服,还剩下%s" % (meimei,money))
                return money

        def big_manager():
                return (jiejie_hobby,meimei_hobby)

        return big_manager

func = family()
# func = big_manager
print(func,type(func))
# func() = big_manager()
tup = func()
print(tup,type(tup))

# 调用姐姐
# jiejie = tup[0]
# jiejie()

res1 = tup[0]()
print(res1)
# 调用妹妹
# meimei = tup[1]
# meimei()

res2 = tup[1]()
print(res2)

执行

[[email protected] python]# python3 test.py
<function family.<locals>.big_manager at 0x7fee9c4f21e0> <class ‘function‘>
(<function family.<locals>.jiejie_hobby at 0x7fee9c4f20d0>, <function family.<locals>.meimei_hobby at 0x7fee9c4f2158>) <class ‘tuple‘>
姐姐小红喜欢买零食,买了辣条钱还剩下60
60
妹妹小明喜欢买衣服,还剩下30
30

示例3

def outer(val):
    def inner(num):
        return val + num
    return inner

func = outer(10)
# func = inner
res = func(5)
print(res)

执行

[[email protected] python]# python3 test.py
15

过程

    func = outer(10)
    val 形参接收到实参值10
    因为内函数使用了外函数的局部变量val,val与内函数发生绑定,延长val的生命周期
    res = func(5)
    num 形参接收到实参值5
    return 10 + 5 => return 15 返回到函数的调用处
    func(5) 是调用处 所以
    res = 15

1.4 获取闭包函数使用的变量

闭包函数.__closure__  返回单元cell  , cell 里面存的是对应的绑定变量
res = func.__closure__  # 获取到一个元组
res = res[0].cell_contents # res[0] 获取元组当中的第一个值 是一个cell单元 通过单元.cell_contents来获取其中的值,就会知道绑定的变量是谁了. cell_contents是一个属性
print(res,type(res))
# print(res.cell_content)
# (<cell at 0x000001D6DAE17708: int object at 0x000000005EC26D30>,)

示例

def outer(val):
        def inner(num):
                return val + num
        return inner

func = outer(10)
# func = inner
res = func(5)
print(res)
print(func.__closure__)
print(func.__closure__,type(func.__closure__))
res = func.__closure__[0]
print(res,type(res))

res = func.__closure__[0].cell_contents
print(res,type(res))

执行

[[email protected] python]# python3 test.py
15
(<cell at 0x7fe07763b7f8: int object at 0x7fe07750c7e0>,)
(<cell at 0x7fe07763b7f8: int object at 0x7fe07750c7e0>,) <class ‘tuple‘>
<cell at 0x7fe07763b7f8: int object at 0x7fe07750c7e0> <class ‘cell‘>
10 <class ‘int‘>

1.5 闭包的意义

  • 闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.

模拟鼠标点击次数

num = 0
def click():
    global num
    num += 1
    return num
res = click()
res = click()
res = click()
# num = 100  恶意串改,我们获取的值就会出现错误
res = click()
res = click()
print(res)

使用闭包函数重写鼠标点击次数

def click():
        x = 0
        def func():
                nonlocal x
                x+=1
                return x
        return func

click  = click()
res = click()
res = click()
res = click()
x = 100          #恶意修改,但是不影响结果
res = click()
res = click()
print(res)

执行

[[email protected] python]# python3 test.py
5

二 locals 和 globals

2.1 locals()

返回字典,获取当前作用域的所有内容

  • 如果在函数里:获取locals()调用之前,该作用域出现的内容
  • 如果在函数外:获取locals()打印返回值之前,该作用域出现的内容
a = 1
b = 2
print(locals())

执行

[[email protected] python]# python3 test.py
{‘__name__‘: ‘__main__‘, ‘__doc__‘: None,     如果在函数里:获取locals()调用之前,该作用域出现的内容\n    如果在函数外:获取locals()打印返回值之前,该作用域出现的内容\n‘, ‘__package__‘: None, ‘__loader__‘: <_frozen_importlib_external.SourceFileLoader object at 0x7ffa9ddb7208>, ‘__spec__‘: None, ‘__annotations__‘: {}, ‘__builtins__‘: <module ‘builtins‘ (built-in)>, ‘__file__‘: ‘test.py‘, ‘__cached__‘: None, ‘a‘: 1, ‘b‘: 2, ‘func‘: <function func at 0x7ffa9de8ae18>,      #全局中又这个函数,但是函数内部的局部变量不能获取‘res‘: {...}, ‘c‘: 3}

所在作用域是局部命名空间,获取locals() 调用之前所出现的所有局部命名空间内容

c=3
d = 4
def func():
    a = 1
    b = 2

    res = locals()
    c = 3
    print(res)

f = 5
func()

执行

[[email protected] python]# python3 test.py
{‘b‘: 2, ‘a‘: 1}

2.2 globals()

返回字典,获取全局作用域的所有内容

  • 如果在函数里: 获取globals()调用之前,全局作用域出现的内容
  • 如果在函数外: 获取globals()打印返回值之前,全局作用域出现的内容

globals在全局作用域中,只获取globals 打印返回值之前的所有全局空间的内容

a = 1
b = 2
res = globals()
print(res)
c = 3

执行

[[email protected] python]# python3 test.py
{‘__name__‘: ‘__main__‘, ‘__doc__‘: None, ‘__package__‘: None, ‘__loader__‘: <_frozen_importlib_external.SourceFileLoader object at 0x7fcd746f5208>, ‘__spec__‘: None, ‘__annotations__‘: {}, ‘__builtins__‘: <module ‘builtins‘ (built-in)>, ‘__file__‘: ‘test.py‘, ‘__cached__‘: None, ‘a‘: 1, ‘b‘: 2, ‘res‘: {...}}

globals在局部作用域中,也仍然获取全局空间的所有内容,但是是在globals,打印返回值之前的所有.

c = 13
d = 14
def func():
        a = 11
        b = 12
        res = globals()
        print(res)
f = 19
func()

执行

[[email protected] python]# python3 test.py
{‘__name__‘: ‘__main__‘, ‘__doc__‘: None, ‘__package__‘: None, ‘__loader__‘: <_frozen_importlib_external.SourceFileLoader object at 0x7f16a5144208>, ‘__spec__‘: None, ‘__annotations__‘: {}, ‘__builtins__‘: <module ‘builtins‘ (built-in)>, ‘__file__‘: ‘test.py‘, ‘__cached__‘: None, ‘c‘: 13, ‘d‘: 14, ‘func‘: <function func at 0x7f16a5217e18>, ‘f‘: 19}

只获取全局,没有ab的值

动态创建全局变量 利用globals

  • globals 返回的是一个系统的全局字典,键是变量名,值是该标量所指向的值
dic = globals()
dic[‘hero‘] = "风流倜傥,高大威猛,威武帅气,万人迷"
print(hero)

# 动态创建5个全局变量p1~p5
def func():
        for i in range(1,6):
                dic["p%d" % (i)] = i

func()
print(p1)
print(p2)
print(p3)
print(p4)
print(p5)

执行

[[email protected] python]# python3 test.py
风流倜傥,高大威猛,威武帅气,万人迷
1
2
3
4
5

原文地址:https://www.cnblogs.com/zyxnhr/p/12285651.html

时间: 2024-11-05 11:58:03

016.Python闭包函数以及locals和globals的相关文章

python之函数用法locals()

# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法locals() #locals() #说明:查找局部变量,返回一个名字/值对的字典对象.只具备查找权限 ''' locals(...) locals() -> dictionary Update and return a dictionary containing the current scope's local variables. ''' #案例 def test(): na

Python 闭包函数

一.定义: 1. 定义在函数内部的函数 2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用那么该内部函数就称为闭包函数 x=1 def f1(): x=11111111111 def f2(): print(x) return f2 func=f1() 二.闭包函数的应用:惰性计算 def index(url): # url='https://www.python.org' def get(): # return requests.get(url).text print(reques

python闭包函数

闭包函数是在一个函数内部又定义了一个函数,外部函数的返回值是内部函数的引用. def func_out(m): n = m def func_inner(): nonlocal n n += 1 print(n) return func_inner 执行外部函数func_out()后,返回的是内部函数func_inner的引用,内部函数的状态还存在. inner = func_out(5) inner() inner() inner() 结果: 678 闭包的用途: 1. 惰性求值(或延迟求值)

python开发函数进阶:命名空间,作用域,函数的本质,闭包,内置方法(globales)

一,命名空间 #局部命名空间#全局命名空间#内置命名空间 #三者的顺序#加载顺序 硬盘上--内存里#内置-->全局(从上到下顺序加载进来的)-->局部(调用的时候加载) 1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 #全局命名空间 5 a = 5 6 b = 8 7 #局部命名空间(函数) 8 def my_max(): 9 c = a if a > b else b 10 return c 11 m = my_max() 12 pr

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

python命名空间与闭包函数详解

python命名空间与闭包函数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客主要介绍的知识点如下: 1>.三元运算 2>.命名空间 3>.global与nonlocal 4>.函数即变量 5>.嵌套函数 6>.闭包函数 一.三元运算 1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yi

python 函数的作用域,闭包函数的用法

一.三元表达式 if条件成功的值    if  条件   else else条件成功的值 #if条件成立的结果 if 条件 else else条件成立的结果 # a = 20 # b = 10 # c = 5 if a>b else 10 # print(c) 二.函数的命名空间 命名空间一共分为三种: 全局命名空间 局部命名空间 内置命名空间 *内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的

python之函数闭包、可迭代对象和迭代器

一.函数名的应用 # 1,函数名就是函数的内存地址,而函数名()则是运行这个函数. def func(): return print(func) # 返回一个地址 # 2,函数名可以作为变量. def func1(): print(666) f1 = func1 f2 = f1 f2() # 就等于func1() 此时执行函数 # 3,函数名可以作为函数的参数. def func1(): print(666) def func2(x): x() func2(func1) # 输出666 func