1.闭包定义
外函数中定义内函数,内函数运用外函数的临时变量,外函数返回值是内函数的引用。构成了一个闭包。
(内函数+外函数的临时变量)
2.引用与地址
地址?有没有括号?
引用,即存地址。举个例子:a=1,内存中有个地方存了1,用变量名a存1所在内存位置的引用/地址。
函数名后无括号——表示地址/引用
函数名后有括号——表示调用函数
3.闭包存在的理由
函数结束时,会将临时变量的内存释放。使用闭包返回内函数时,外函数虽然已经结束,但临时变量依然有效。
4.内函数修改外函数的临时变量
外函数绑定给内函数的是局部变量,为了在内函数中修改这个局部变量的值,可以:
(1)关键字声明:在python3中用nonlocal关键字声明一个变量,表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。
(2)修改数据类型:在python2中没有nonlocal,将闭包变量改成可变类型数据,再进行修改。
def outer(a):
b=10
c=[a]#修改临时变量类型
def inner():
nonlocal b#没有这一句的话,b+=1会报错
b+=1
c[0]+=1
print(b)
print(c[0])
return inner
result=outer(1)#result后面没括号,只是存地址,但不执行
result()#真正的调用函数
5.内函数可以传入新的外函数不能提供的变量,临时变量具能够保持其持久性
def outer(x):
def inner(y):
nonlocal x
x+=y
return x
return inner
a = outer(10)
print(a(1))#11
print(a(3))#14
重点关注a=outer(10)以及a(1),传入了两个参数:传入10作为x,传入1作为y,x的值虽然通过nonlocal可以修改,但每次开启内函数时x始终还是10,外函数的临时变量可被修改但每次开启内函数使用同一份临时变量
6.闭包的作用
(1)装饰器Decorator
(2)面向对象,面向接口
(3)单例模式
7.__closure__属性
定义一个元组用于保存闭包的所有外部变量
def outer(x,y):
def inner():
print(x,y)
return inner
a = outer(10,20)
print(a.__closure__[0].cell_contents)#10
print(a.__closure__[1].cell_contents)#20
print(a.__closure__)#(<cell at 0x0000025488E7B4C8: int object at 0x0000000055846F00>, <cell at 0x0000025488E7B828: int object at 0x0000000055847040>)
print(a.__closure__[0])#<cell at 0x0000025488E7B4C8: int object at 0x0000000055846F00>
8.Python的namespace
一共有三种 namespace,分别为:
local namespace: 作用范围为当前函数或者类方法
global namespace: 作用范围为当前模块
build-in namespace: 作用范围为所有模块
当函数/方法、变量等信息发生重名时,Python会按照 “local namespace -> global namespace -> build-in namespace”的顺序搜索用户所需元素,并且以第一个找到此元素的 namespace 为准。
同时,Python中的内建函数locals()和globals()可以用来查看不同namespace中定义的元素。
s = "string in global"
num = 99
def numFunc(a, b):
num = 100
print("print s in numFunc: ", s)#print s in numFunc: string in global
def addFunc(a, b):
s = "string in addFunc"
print("print s in addFunc: ", s)#print s in addFunc: string in addFunc
print("print num in addFunc: ", num)#print num in addFunc: 100
print("locals of addFunc: ", locals())#locals of addFunc: {'s': 'string in addFunc', 'b': 6, 'a': 3, 'num': 100}
# print
return "%d + %d = %d" % (a, b, a + b)
print("locals of numFunc: ", locals())
# locals of numFunc: {'addFunc': <function numFunc.<locals>.addFunc at 0x000001A78F0A6A60>, 'b': 6, 'a': 3, 'num': 100}
# print
return addFunc(a, b)
numFunc(3, 6)
print("globals: ", globals())#globals: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001A78EE3B240>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/PycharmProjects/offer/try2.py', '__cached__': None, 's': 'string in global', 'num': 99, 'numFunc': <function numFunc at 0x000001A78ED42E18>}
参考网址:
https://www.cnblogs.com/Lin-Yi/p/7305364.html
https://www.cnblogs.com/cicaday/p/python-closure.html
http://python.jobbole.com/82296/