Python 闭包

Python Closures

Posted by BlueFat on Saturday, August 13, 2022

闭包

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

    1. counter产生c和inc两个局部变量
    1. foo获取了counter()的结果,inc指向的引用地址954248,inc引用到c地址992628
    1. counter( )函数执行完,局部变量inc和c标识符都消亡了,但是c和inc被foo引用了不会消亡。
    1. 由于外层函数已经执行结束了,内层函数对象没有消亡,什么时候调用不知道,但此时内层函数用到外层函数的自由变量c
    1. 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