嵌套函数中的可变范围 [英] Variable scope in nested functions

查看:81
本文介绍了嵌套函数中的可变范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以解释为什么以下程序失败:

Could someone explain why the following program fails:

def g(f):
  for _ in range(10):
    f()

def main():
  x = 10
  def f():
    print x
    x = x + 1
  g(f)

if __name__ == '__main__':
  main()

显示以下消息:

Traceback (most recent call last):
  File "a.py", line 13, in <module>
    main()
  File "a.py", line 10, in main
    g(f)
  File "a.py", line 3, in g
    f()
  File "a.py", line 8, in f
    print x
UnboundLocalError: local variable 'x' referenced before assignment

但是,如果我只是将变量x更改为数组,它将起作用:

But if I simply change the variable x to an array, it works:

def g(f):
  for _ in range(10):
    f()

def main():
  x = [10]
  def f():
    print x[0]
    x[0] = x[0] + 1
  g(f)

if __name__ == '__main__':
  main()

与输出

10
11
12
13
14
15
16
17
18
19

我感到困惑的原因是,如果从f()无法访问x,为什么如果x是数组则可以访问它?

The reason I am confused is, if from f() it can't access x, why it becomes accessible if x is an array?

谢谢.

推荐答案

但是这个答案说问题在于分配给x.就是这样 然后打印就可以了,不是吗?

But this answer says the problem is with assigning to x. If that's it, then printing it should work just fine, shouldn't it?

您必须了解事情发生的顺序.在甚至编译和执行python代码之前,称为 parser 的内容会通读python代码并检查语法.解析器所做的另一件事是将变量标记为局部变量.当解析器在本地作用域中的代码中看到一个分配时,该分配左侧的变量将标记为local.在这一点上,甚至还没有编译任何东西-更不用说执行了,因此没有赋值;该变量仅被标记为局部变量.

You have to understand the order in which things happen. Before your python code is even compiled and executed, something called a parser reads through the python code and checks the syntax. Another thing the parser does is mark variables as being local. When the parser sees an assignment in the code in a local scope, the variable on the lefthand side of the assignment is marked as local. At that point, nothing has even been compiled yet--let alone executed, and therefore no assignment takes place; the variable is merely marked as a local variable.

解析器完成后,将编译并执行代码.当执行到达打印语句时:

After the parser is finished, the code is compiled and executed. When execution reaches the print statement:

def main():
  x = 10     #<---x in enclosing scope

  def f():
    print x    #<-----

    x = x + 1  #<-- x marked as local variable inside the function f()

print语句看起来应该继续,并在封闭范围(LEGB查找过程中的'E')上打印x.但是,由于解析器先前将x标记为f()内的局部变量,因此python不会越过局部范围(LEGB查找过程中的"L")来查找x.由于在执行打印x"时尚未将x分配给本地范围,因此python会吐出一个错误.

the print statement looks like it should go ahead and print the x in the enclosing scope (the 'E' in the LEGB lookup process). However, because the parser previously marked x as a local variable inside f(), python does not proceed past the local scope (the 'L' in the LEGB lookup process) to lookup x. Because x has not been assigned to in the local scope at the time 'print x' executes, python spits out an error.

请注意,即使永远不会执行发生分配的代码,解析器仍会将分配左侧的变量标记为局部变量.解析器不知道事情将如何执行,因此它盲目地搜索整个文件中的语法错误和局部变量,即使在永远无法执行的代码中也是如此.以下是一些示例:

Note that even if the code where an assignment occurs will NEVER execute, the parser still marks the variable on the left of an assignment as a local variable. The parser has no idea about how things will execute, so it blindly searches for syntax errors and local variables throughout your file--even in code that can never execute. Here are some examples of that:

def dostuff ():
    x = 10 

    def f():
        print x

        if False:  #The body of the if will never execute...
            a b c  #...yet the parser finds a syntax error here


    return f

f = dostuff()
f()



--output:--
File "1.py", line 8
     a b c
      ^
SyntaxError: invalid syntax

解析器在标记局部变量时会做同样的事情:

The parser does the same thing when marking local variables:

def dostuff ():
    x = 10 

    def f():
        print x

        if False:  #The body of the if will never execute...
            x = 0  #..yet the parser marks x as a local variable

    return f

f = dostuff()
f()

现在看看执行最后一个程序会发生什么:

Now look what happens when you execute that last program:

Traceback (most recent call last):
  File "1.py", line 11, in <module>
    f()
  File "1.py", line 4, in f
    print x
UnboundLocalError: local variable 'x' referenced before assignment

当执行语句'print x'时,由于解析器将x标记为局部变量,因此x的查找将在局部范围内停止.

When the statement 'print x' executes, because the parser marked x as a local variable the lookup for x stops at the local scope.

功能"并不是python独有的-它也发生在其他语言中.

That 'feature' is not unique to python--it happens in other languages too.

对于数组示例,当您编写时:

As for the array example, when you write:

x[0] = x[0] + 1

告诉python查找一个名为x的数组,并为其第一个元素分配一些内容.由于在本地范围内没有分配给任何名为x的东西,因此解析器不会将x标记为本地变量.

that tells python to go lookup up an array named x and assign something to its first element. Because there is no assignment to anything named x in the local scope, the parser does not mark x as a local variable.

这篇关于嵌套函数中的可变范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆