为什么以下代码无效:
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()
会在UnboundLocalError: local variable 'x' referenced before assignment
行提供if x == 5:
。为什么稍后在代码中更改x的值会使此条件无效?
答案 0 :(得分:3)
Python首先需要检测哪些变量是本地的,以及哪个变量是从外部范围获取的。为了做到这一点,它会查找作业,例如:
def foo1(x=5):
def bar():
if x == 5:
x = 6 # an assignment, so local variable
print(x)
bar()
关键是,分配可以在任何地方发生。例如在最后一行。然而,从某个地方开始,x
就位于本地。因此,在您的第一个代码片段中,x
是一个局部变量。但是你在它被分配(有界)之前获取它,所以Python会在它上面出错。
在python-3.x中,您可以使用 nonlocal
关键字从外部范围访问x
:
def foo1(x=5):
def bar():
nonlocal x
if x == 5:
x = 6
print(x)
bar()
对于python-2.x,您可以例如将变量分配给函数,例如:
def foo1(x=5):
def bar():
if bar.x == 5:
bar.x = 6
print(bar.x)
bar.x = x
bar()
但请注意,两者不等同。因为在前者中如果你改变x
,它也会改变x
范围内的foo1
。在后一个示例中,您只需修改bar.x
。当然,如果这些是可变对象,则会改变同一个对象。