我有一个演示示例:
def outer(func):
def inner(foo):
arg_inner=some_value
func(arg_inner,foo)
return inner
def third_party(arg1,arg2):
#do something
final = outer(third_party)
final(3)
我想知道内部函数在被调用时如何知道func
的值。内部功能和外部的范围如何连接?
答案 0 :(得分:3)
编译器连接它们。
在汇编outer
和inner
时,func
中的outer
名称被标记为闭包,inner
中的自由变量被标记为func
。执行时,解释器会知道将outer
名称的引用从inner
作为闭包单元附加到>>> import dis
>>> dis.dis(outer)
2 0 LOAD_CLOSURE 0 (func)
3 BUILD_TUPLE 1
6 LOAD_CONST 1 (<code object inner at 0x1079a5ab0, file "<stdin>", line 2>)
9 MAKE_CLOSURE 0
12 STORE_FAST 1 (inner)
4 15 LOAD_FAST 1 (inner)
18 RETURN_VALUE
>>> inner = outer(lambda a, b: None)
>>> dis.dis(inner)
3 0 LOAD_DEREF 0 (func)
3 LOAD_GLOBAL 0 (arg_inner)
6 LOAD_FAST 0 (foo)
9 CALL_FUNCTION 2
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
函数对象。
您可以在字节码的反汇编中看到结果:
LOAD_CLOSURE
func
将inner
名称包含在MAKE_CLOSURE
的封闭中以供使用; LOAD_CONST
构建一个函数对象(来自加载了inner
的字节代码对象),附加的闭包单元格作为元组。在LOAD_DEREF
中,func
操作码会加载inner
闭包中的值。
可以在生成的>>> inner.func_closure
(<cell at 0x107a25a28: function object at 0x107a28b18>,)
>>> inner.func_code.co_freevars
('func',)
>>> inner.func_closure[0].cell_contents
<function <lambda> at 0x107a28b18>
函数对象上找到闭包:
inner
因此{{1}}函数对象带有闭包,以便以后解除引用。
答案 1 :(得分:0)