python中嵌套函数的可变范围

时间:2013-08-08 13:23:47

标签: python variables scope

我有一个演示示例:

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的值。内部功能和外部的范围如何连接?

2 个答案:

答案 0 :(得分:3)

编译器连接它们。

在汇编outerinner时,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

funcinner名称包含在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)