什么是闭包?
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
闭包的特点
在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
下面是典型的闭包代码段:
def outer(a):
b=13
def inner():
print(a+b)
return inner
if __name__ == '__main__':
hwq1 = outer(13)
hwq() #26
hwq2 = outer(12)
hwq2() #25
外函数return的是内函数的引用,因为python中任何东西都是对象,对象的引用其实就是对象在内存中的地址,有点类似与C++中的指针
比如a=1,在一个内存区域的值是1,a在另一个内存块,a上面的值是1那个内存块的地址,所以a里面存的是数值1的引用
再看main里面的代码,hwq1存的是outer返回值的引用,也就是inner函数的入口地址,hwq()其实就是函数调用,通过hwq的地址找到入口,然后执行inner函数
外函数把临时变量绑定给了内函数
闭包是一个特殊的情况,一般函数结束的时候,会把自己的内存区域释放,包括自己的临时变量,但是在闭包中外函数发现自己的临时变量会在将来的内部函数用到,自己结束时,会把外函数的临时变量和内函数绑定在一起,所以外函数结束了,调用内函数仍然能够使用外函数的临时变量
另外我定义了两个hwq和hwq1,虽然它们执行的内函数代码是一样的,但是对象是不一样的,就是说内函数的入口地址不一样,所以执行结果是26和25
闭包中内函数怎么修改外函数局部变量?
在python中要修改外函数的变量有两种方法:
1.global声明全局变量
2.变量是可变类型变量的时候
在python3中可以使用nonlocal声明一个变量,表示这个变量不是局部变量空间的,需要向上一层变量空间寻找
在python2中,没有nonlocal关键字,所以我们需要把变量改成可变类型数据,list,dict,set
def outer(a):
b=13
c=[a]
def inner():
nonlocal b
b+=1
c[0]+=1
print(b)
print(c[0])
return inner
if __name__ == '__main__':
hwq1 = outer(12)
hwq1() # 26 13
还有就是,一旦外函数被调用了一次,是一次哦,返回内函数的引用,每次调用内函数,使用的外函数变量实际只有一份,也就是是说在同一个内存块
比如说:
def outer():
a=10
def inner():
nonlocal a
a+=1
return a
return inner
if __name__ == '__main__':
hwq = outer()
print(hwq()) #11
print(hwq()) #12
print(hwq()) #13
我们可以想到闭包的这些特性可以用作装饰器,也可以通过这种方式实现面向对象编程