提问人:artemonster 提问时间:8/23/2021 更新时间:9/7/2021 访问量:69
python 闭包何时进行捕获?
When python closures are exactly doing their capture?
问:
这是 python 中一个相当不言自明的代码片段:
globl = 1
def foo():
def bar():
return free+capture
capture = globl #not seen, when bar is defined
return bar
free = 2
a = foo()
globl = 4
b = foo()
print(a()) #3
print(b()) #6
print(a.__closure__[0].cell_contents) # 1
print(b.__closure__[0].cell_contents) # 4
定义 'bar' 时,“free”和 'captured' 变量都是自由的。它们不存在于父环境中,也不存在于根中。当“bar”从“foo”返回时,“捕获”将被捕获。从一堆!
因此,我假设python在返回函数时关闭环境。为什么会这样?为什么不在“酒吧”的定义时间?
如果我们用 lambda 替换 bar,相同的代码段也有效:
bar = lambda : free+capture
答:
2赞
Yilmaz
9/7/2021
#1
在编译时,当 Python 遇到一个函数时,它会做出一些决定。它查看函数中的所有内容,它不创建范围或命名空间,但它确定哪些变量将是局部的或非局部的。
当你运行 foo() 时,这意味着在 的运行时,函数被创建,python 将 “free” 和 “capture” 确定为非本地变量,因此已经有了对 free 变量的引用。foo
bar
bar
“free”和“capture”位于两个不同的作用域中,但始终引用相同的“值”。当 python 确定 “bar” 的局部变量时,它会创建一个单元格对象。
因此,当外部函数“foo”完成运行时,这个“Cell”对象仍然存在,因此当调用内部函数“bar”时,它仍然获得相同的值。
评论
capture