outer() 执行完毕
outer
的栈帧销毁,但 z
不会立即回收!z
已被封装进 inner
的闭包单元格(__closure__[0]
),其生命周期延长至与 inner
函数对象共存。是这样吗
def outer():
……z = 10 # ① 普通局部变量
…………def inner():
……………print(z) # ② z被识别为自由变量
…………return inner
fn = outer() # ③ 调用outer(),返回inner函数对象
不对,语义分析时,从函数内扫描,发现未在l中找到变量就标记为自由变量,外层函数里面的变量处也会标记,从反编译可以看出dis.dis(outer)
…
2 0 LOAD_CONST 1 (10)
2 STORE_DEREF 0 (z) # 注意是STORE_DEREF不是STORE_FAST
3 4 LOAD_CLOSURE 0 (z)
6 BUILD_TUPLE 1
8 LOAD_CONST 2 (<code object inner at 0x...>)
10 LOAD_CONST 3 ('outer.<locals>.inner')
12 MAKE_FUNCTION 8 (closure)
14 STORE_FAST 0 (inner)
5 16 LOAD_FAST 0 (inner)
18 RETURN_VALUE
…
当执行outer函数时,z=10处 会变成闭包单元存储,创建inner函数对象时,将当前作用域绑定到堆区闭包单元,out调用结束,outer栈帧销毁,但cell对象还存在堆区,inner对象还在引用,所以仍可以inner.__closure__获取