Python中的函数范围

时间:2017-10-05 14:05:42

标签: python algorithm python-3.x function scope

鉴于此代码块:

def f(x):
    def g():
        x = "abc"
        print("x =", x)
    def h():
        z = x
        print("z =", z)
    x += 1
    print("x =", x)
    h()
    g()
    print("x =", x)
    return g

x = 3
z = f(x)
print("x =", x)
print("z =", z)
z()

问题:当我没有定义一个名为z的函数时,最后一行如何返回值“x = abc”?

在代码中编辑:我意外地将g的参数设置为x,当它应该为空时。

3 个答案:

答案 0 :(得分:2)

  

最后一行如何返回" x = abc"的值?当我还没有定义一个名为z的函数时?

要查看代码的执行方式 - 以及为什么最后一行输出为x = abc,我已在代码中添加了一些print语句:

def f(x):
    print('-----------control is in "f"-----------')
    def g():
        print('-----------control is in "g-----------')
        x = "abc"
        print("x =", x)
    def h():
        print('-----------control is in "h"-----------')
        z = x
        print("z =", z)
    x += 1
    print("x =", x)
    h()
    g()
    print("x =", x)
    return g

x = 3
z = f(x)
print("x =", x)
print("z =", z)
z()

上述修改后的程序输出:

-----------control is in "f"-----------
x = 4
-----------control is in "h"-----------
z = 4
-----------control is out of "h"-----------
-----------control is in "g"-----------
x = abc
-----------control is out of "g"-----------
x = 4
-----------control is out of "f"-----------
x = 3
z = <function f.<locals>.g at 0x7f2aee25b6a8>
-----------control is in "g"-----------
x = abc
-----------control is out of "g"-----------

如您所见,在代码的最后部分调用函数g,即行x = abc的打印方式。 如何?由于这一行:

z = f(x)

f函数返回 函数对象 ; g。然后,对g函数的引用绑定到变量z。您可以在上面的输出中自己看到:

z = <function f.<locals>.g at 0x7f2aee25b6a8>

在代码的最后,您调用函数 - g - 绑定到z

z()

答案 1 :(得分:1)

这与范围无关。如果你的最后一行是

 g()
如你所料,它不会起作用。但是,有了这条线

 z = f(x)

将名称z绑定到f(x)的返回值,g(x)是函数z()的正文。在您致电g时,功能z不可见,但g(x)与其绑定。

附加说明:如果x未重新定义x的值,则会将f(x)的值保留为"defaults": { "styleExt": "css", "component": {} }, "serve": { "port": 8080 } } 与范围有关,它将是闭包

答案 2 :(得分:0)

您尚未明确定义名为&#34; z&#34;的函数,但z已绑定到函数,因为它是f(x)返回的内容。

稍微减少(不必要的大)示例:

>>> def f():
...     def g():
...         print("hello")
...     return g
... 
>>> f()
<function g at 0x00000000024AC978>

我们看到f()返回(本地定义的)函数g

>>> z = f()
>>> z
<function g at 0x00000000024AC9E8>

z绑定到f()返回的函数g

(您可能已经注意到此g的地址与之前的g不同。这是因为每次调用f()都会创建一个返回的新函数。)

>>> z()
hello

这会调用f返回的函数,这样做:

>>> f()()
hello