我读了一个关于闭包的例子
def outer():
x = 1
def inner():
print x # 1
return inner
变量x的生命周期直到函数外部运行的时间。 当我调用外部并返回内部地址时,变量x应该已经死亡,因为函数外部已经退出但仍然可以通过返回的内部函数来获取它吗?
python variable scope in nested functions
这个链接回答说,当外部将内部函数返回给调用者时,存储内部使用的变量的值,但是
现在看到这段代码
def outer():
x = 1
def inner():
print x*n # n not defined anywhere
return inner
我运行了这段代码 当我调用outer时,这段代码不会给出任何错误,这意味着python在运行外部时不会检查内部函数使用的变量。那怎么知道它必须保留' x'退出后?
答案 0 :(得分:3)
记住x
的方式是因为python有一个特殊的__closure__
属性,它记住了本地函数需要的封闭范围内的对象,并保留reference
所以它可以用于本地函数:
def outer():
x = 1
def inner():
print(x)
return inner
o = outer()
print(o.__closure__)
(<cell at 0x7fa18a2fc588: int object at 0x9f8800>,)
如果您分配o = outer()
然后调用o()
,则调用inner
函数,您将收到错误,调用outer()
不会调用内部函数。
如果您要声明一个函数f
并将print(n)
置于正文中,那么除非您实际调用f
,否则您将不会收到错误,因此相同的逻辑适用于您的内部函数,您实际上并没有使用outer()
调用它,因此您不会收到错误:
def f():
print(n) # will only error when we actually call `f()`
如果在调用inner
时调用outer
函数会导致失败,请考虑以下函数工厂,我们在其中使用指数e
来提升i
到:
def raise_exp(e):
def power(i):
return i ** e # n not defined anywhere
return power
sq = raise_exp(2) # set exponent but does not call power
print(sq(2)) # now we actually all power
cube = raise_exp(3)
print(cube(3))
25
27
答案 1 :(得分:2)
变量x的生命周期直到函数外部运行
没有。 x
只要可以从某个地方到达,就会活着。而且,它来自inner
函数。
当我调用outer时,这段代码没有给出任何错误,这意味着python在运行外部时不会检查内部函数使用的变量
n
可以在调用outer
之后定义为,而调用其结果之前为 inner
。在这种情况下,inner
的身体是完全合法的。
如果您没有返回inner
,那么就没有理由保留x
,因为您无法inner
,因此可以&x
#39;以某种方式将{{1}}纳入计算。