这里的问题在于Python如何绑定names to 变量.
任何时候你在函数中编写作业(例如a = b
or a += b
), Python 将绑定该名称locally为了entire功能范围。这意味着在函数外部声明的具有该名称的任何变量都是ignored.
例如:
a = 1 # This variable is ignored.
def foo():
print(a) # "a" hasn't been defined yet!
a = 2 # This causes "a" to bind to a local variable.
这将产生一个UnboundLocalError
在 print 语句中,因为 Python 看到了a
被分配给函数的后面,并在本地绑定它,忽略您在函数外部定义的变量。自从a
仅定义afterprint 语句,你会得到一个错误。
这可能会非常令人困惑,因为删除a += 2
行将导致打印语句按预期工作!
解决方案是显式地告诉Pythonnot在本地绑定名称。这可以通过global
and nonlocal
关键字,例如:
a = 1
def foo():
nonlocal a # or: global a
print(a)
a += 2
global
告诉 Python 将名称绑定到模块的全局范围内,而nonlocal
(Python 3 中引入)告诉 Python 绑定到包围范围(例如,如果您在函数内定义函数)。
对此有一个很好的解释(带有示例)文档 https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces :-)
一旦我们理解了这些规则,我们就可以看到您的第一个示例失败了,因为您试图增加一个尚不存在的变量。output += 1
相当于output = output + 1
,这会触发本地名称绑定。
另一方面,您的第二个示例不会触发错误,因为您没有分配给output
(你是mutating相反),因此它将绑定到您定义的全局变量。