考虑以下python片段(我正在运行Python 3)
name = "Sammy"
def greet():
name = 'johny'
def hello():
print('hello ' + name) # gets 'name' from the enclosing 'greet'
hello()
greet()
这会产生预期的输出hello johny
然而,
x = 50
def func1():
x = 20
def func2():
print("x is ", x) # Generates error here
x = 2
print("Changed the local x to ",x)
func2()
func1()
print("x is still ",x)
生成UnboundLocalError: local variable 'x' referenced before assignment
。
为什么第一个代码段有效,而第二个则没有?
答案 0 :(得分:4)
错误实际上是由以下行(间接)引起的,即x = 2
。尝试注释掉该行,您将看到该功能正常工作。
对于名为x
的变量赋值的事实使x
在编译时的函数本地化,但是,执行时对x
的第一次引用失败,因为在执行print()
语句时,它在当前范围中尚不存在。
使用func2()
中的nonlocal
更正
def func2():
nonlocal x
print("x is ", x)
x = 2
print("Changed the local x to ",x)
第一个函数(greet()
)工作的原因是因为可以读取外部作用域中的变量,但是,除非指定变量存在于外部作用域中,否则不能分配它们(使用nonlocal
或global
)。
但是,您可以指定一个同名的变量,它将创建一个新的局部变量,而不是外部作用域中的变量。所以这也有效:
def func1():
x = 20
def func2():
x = 2
print('Inner x is', x)
func2()
print('Outer x is', x)
此处x
在被引用之前被分配。这会在函数x
的范围内创建一个名为func2()
的新变量,该变量会隐藏x
中定义的func1()
。