闭包
def counter():
c=[0]
def inc():
c[0]+=1
return c[0]
return inc # 函数对象
foo=counter()
print(foo(),foo(),foo())
c=100
print(foo())
1 2 3
4
return inc() 不可以用(),返回结果,会消亡
counter生成c和inc,消亡,但c inc被foo引用了不会消亡
foo指向c和inc
-
- counter产生c和inc两个局部变量
-
- foo获取了counter()的结果,inc指向的引用地址954248,inc引用到c地址992628
-
- counter( )函数执行完,局部变量inc和c标识符都消亡了,但是c和inc被foo引用了不会消亡。
-
- 由于外层函数已经执行结束了,内层函数对象没有消亡,什么时候调用不知道,但此时内层函数用到外层函数的自由变量c
-
- foo指向的函数对象,要使用counter的c,c指向的列表不消亡,由这个内层函数对象保存这个列表,称为闭包。
def counter():
c=0
def inc():
c+=1 # c=是局部变量,不是闭包了
return c
return inc
f2=counter()
f2() #报错
nonlocal 闭包
def counter():
count=0
def inc(): #将变量标记为不在本地作用域定义的,而是在上级的某一级局部作用域中定义的,但不能是全局作用域中定义的
nonlocal count # 找外层函数,不能是全局,外层没有会报错
count+=1 # c=是局部变量,不是闭包了
return count
return inc
f2=counter()
f2()
f2()
2
yield闭包
def counter():
def inc():
i=0
while True:
i+=1
yield i
c=inc()
def fn():
return next(c)
return fn
foo2=counter()
print(foo2())
print(foo2())
1
2
def counter():
def inc():
i=0
while True:
i+=1
yield i
c=inc()
return lambda : next(c)
foo2=counter()
print(foo2())
print(foo2())
1
2