gpt4 book ai didi

python - 嵌套函数中的变量范围

转载 作者:太空狗 更新时间:2023-10-29 22:27:04 25 4
gpt4 key购买 nike

谁能解释一下为什么下面的程序失败了:

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 更改为数组,它就可以工作:

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 是可访问的数组?

谢谢。

最佳答案

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 代码甚至被编译和执行之前,称为解析器 的东西会通读 Python 代码并检查语法。解析器做的另一件事是将变量标记为本地变量。当解析器在局部范围内看到代码中的赋值时,赋值左侧的变量被标记为局部。那时,甚至还没有编译任何东西——更不用说执行了,因此没有分配发生;该变量仅被标记为局部变量。

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

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

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

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

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

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

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

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

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()

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

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 的查找在局部范围内停止。

这个“特性”并不是 python 独有的——它也存在于其他语言中。

至于数组的例子,当你这样写的时候:

x[0] = x[0] + 1

告诉 python 去查找一个名为 x 的数组并为它的第一个元素分配一些东西。因为在局部范围内没有对任何名为 x 的东西赋值,所以解析器不会将 x 标记为局部变量。

关于python - 嵌套函数中的变量范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16452942/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com