嵌套函数定义和范围(UnboundLocalError) [英] Nested function definitions and scope (UnboundLocalError)
问题描述
为什么以下代码无效:
def foo1(x=5):
def bar():
if x == 5:
x = 6
print(x)
bar()
此代码有效:
def foo2(x=5):
def bar():
if x == 5:
print('ok')
print(x)
bar()
foo2()
将完全按照您的期望进行操作,但是foo1()
将在行if x == 5:
处给出UnboundLocalError: local variable 'x' referenced before assignment
.为什么稍后在代码中更改x的值会使此条件无效?
foo2()
will do exactly what you expect, but foo1()
will give a UnboundLocalError: local variable 'x' referenced before assignment
at the line if x == 5:
. Why does altering the value of x later on in the code make this conditional invalid?
推荐答案
Python首先需要检测哪些变量是本地变量,以及哪些变量是从外部范围获取的.为此,它会查找作业,例如:
Python needs first to detect what variables are local, and which variable are fetched from an outer scope. In order to do that it looks for assignments, like:
def foo1(x=5):
def bar():
if x == 5:
x = 6 # an assignment, so local variable
print(x)
bar()
重点是,作业可以在任何地方发生.例如在最后一行.但是,从x
本地开始就存在分配.因此,在您的第一个代码片段中,x
是局部变量.但是您在分配它(绑定)之前先获取它,所以Python会在上面出错.
The point is, that the assignment can happen anywhere. For instance on the last line. Nevertheless, from the moment there is an assignment somewhere x
is local. So in your first code fragment, x
is a local variable. But you fetch it before it is assigned (bounded), so Python will error on it.
在python-3 .x ,您可以使用 nonlocal
关键字从外部范围访问x
:
In python-3.x you can use the nonlocal
keyword to access x
from an outer scope:
def foo1(x=5):
def bar():
nonlocal x
if x == 5:
x = 6
print(x)
bar()
对于 python-2 .x ,例如,您可以将变量分配给函数,例如:
For python-2.x, you can for instance assign the variable to the function, like:
def foo1(x=5):
def bar():
if bar.x == 5:
bar.x = 6
print(bar.x)
bar.x = x
bar()
但是请注意,两者不相同.由于在前者中,如果您更改x
,它也会在foo1
范围内更改x
.在后一个示例中,您仅修改bar.x
.当然,如果这些是可变对象,则可以更改同一对象.
Note however that the two are not equivalent. Since in the former if you alter x
, it will be alter the x
in the foo1
scope as well. In the latter example you only modify bar.x
. Of course if these are mutable objects, you alter the same object.
这篇关于嵌套函数定义和范围(UnboundLocalError)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!