Chu*_*ung 6 python scope function
在步骤8,有一个定义为:
def outer():
x = 1
def inner():
print x # 1
return inner
Run Code Online (Sandbox Code Playgroud)
如果我们运行它:
>>> foo = outer()
>>> foo.func_closure # doctest: +ELLIPSIS
Run Code Online (Sandbox Code Playgroud)
它不打印x.根据解释:
一切都按照Python的范围规则工作 - x是我们函数外部的局部变量.当内部打印x在点#1处Python寻找内部的局部变量而没有找到它在封闭范围内查找外部函数,在那里找到它.
但是从可变寿命的角度来看,事情呢?我们的变量x是函数外部的局部变量,这意味着它只在函数外部运行时存在.我们无法在返回外部之后调用内部,因此根据我们的Python工作原理模型,在我们调用内部时,x应该不再存在,并且可能会发生某种类型的运行时错误.
但是,我真的不明白第二段是什么意思.
我理解inner()确实得到x的值,但为什么它不打印x?
谢谢
更新:
谢谢大家的答案.现在我明白了原因." return inner "只是一个指向 inner()的指针,但它没有被执行,这就是为什么inner()不打印x,因为它根本没有被调用
我理解inner()确实得到x的值,但为什么它不打印x?
它没有打印出任何东西,因为你还没有调用内部函数.
>>> def outer():
x = 1
def inner():
print x # 1
return inner
...
>>> func = outer()
>>> func
<function inner at 0xb61e280c>
>>> func()
1
Run Code Online (Sandbox Code Playgroud)
这称为闭包,即使外部函数不再处于堆栈中(已完成执行),但仍然从其返回的内部函数会记住它的状态.(即值x)
>>> def outer():
x = 1
y = 2
def inner():
z=3
print x
return inner
...
>>> func = outer()
>>> func.func_code.co_freevars #returns the variables that were used in closure
('x',)
Run Code Online (Sandbox Code Playgroud)
从源代码中了解python如何决定它是否为闭包:
459 if len(code.co_freevars) == 0:
460 closure = NULL
461 else:
462 len(closure) == len(code.co_freevars)
Run Code Online (Sandbox Code Playgroud)
在py3.x中,您还可以修改内部函数中xusing nonlocal语句的值.
>>> def outer():
x = 1
def inner():
nonlocal x
x += 1
print (x)
return inner
...
>>> func = outer()
>>> func()
2
>>> func()
3
>>> func()
4
Run Code Online (Sandbox Code Playgroud)
你没有打电话inner。您已调用outer,它返回inner,但没有调用它。如果您想调用inner,请执行foo()(因为您将 的结果分配outer()给了名称foo)。
你引用的这段话与这个问题有点无关。您说您已经了解为什么inner会获得 的值x,这就是该段落所解释的内容。基本上,如果在嵌套函数中使用局部变量,并且返回该嵌套函数,则该变量的值将与返回的函数一起存储,即使定义该变量的作用域不再活动。通常完成x后就会消失outer,因为x只是本地的outer。但outer返回后inner,仍然需要访问x。因此被包裹在所谓的闭包中,因此以后x仍然可以访问它。inner