嵌套函数中的python变量范围

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,因为它根本没有被调用

Ash*_*ary 8

我理解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)

  • 对于``nonlocal``语句+1 (3认同)

Bre*_*arn 2

你没有打电话inner。您已调用outer,它返回inner,但没有调用它。如果您想调用inner,请执行foo()(因为您将 的结果分配outer()给了名称foo)。

你引用的这段话与这个问题有点无关。您说您已经了解为什么inner会获得 的值x,这就是该段落所解释的内容。基本上,如果在嵌套函数中使用局部变量,并且返回该嵌套函数,则该变量的值将与返回的函数一起存储,即使定义该变量的作用域不再活动。通常完成x后就会消失outer,因为x只是本地的outer。但outer返回后inner,仍然需要访问x。因此被包裹在所谓的闭包中,因此以后x仍然可以访问它。inner