这是对Python variable scope error
的跟进问题case-1,以下代码
a = 0
def test_immutable():
a += 1
test_immutable()
遇到错误:
UnboundLocalError: local variable 'a' referenced before assignment
原始帖子的答案很好地解释了第一种情况。 a += 1
进行分配,因此使a
为尚未分配任何对象的局部变量,因此引用它会导致UnboundLocalError
。
在下面的第二个示例中,当我将a
替换为array[0]
时,它可以不使用UnboundLocalError
。
情况2,以下代码
array = [0, 0, 0]
def test_mutable():
array[0] += 1
test_mutable()
print(array)
输出
[1, 0, 0]
我猜想这与a
是不可变的而array
是可变的有关。但是,Python如何将这两种情况区别对待?我很困惑。任何帮助表示赞赏。
答案 0 :(得分:1)
您正在观察的问题实际上与可变或不可变类型没有任何关系,这是一个范围界定问题。
考虑以下内容:
a = 0
a += 1
这是有效的,尽管0
是不可变的。
另外,这个:
array = [0, 0, 0]
def test_mutable():
array += [1]
test_mutable()
print(array)
会给你同样的UnboundLocalError
。
问题在于范围界定。当您尝试在函数内部重用a
时,解释器会混淆您所指的a
的含义,因为它首先意识到无论您要计算什么,您都希望将其与名称a
,因此它为您保留了本地名称a
,覆盖了全局a
,但是当您尝试将其用于+= 1
位时,它会意识到本地a
没有任何绑定。
使用array
,特别是array[0]
时,情况有所不同,因为您不是保留名称array
供本地使用,而是继续使用全局{{1} }。
答案 1 :(得分:1)
在像您这样的函数中更新全局变量时,应将其明确声明为全局变量,这将很好地工作。
a = 0
def test_immutable():
global a
a += 1
test_immutable()
因此,在遇到错误的情况下,它假设a
是局部变量,但是在更新它之前没有声明,即a+=1
。如果您不更新函数中的全局变量,则可以使用全局变量而无需显式声明为全局变量。例如:
a = 0
def test_immutable():
print(a)
test_immutable()
对于列表,您不是在更新整个列表,而是在更新列表的元素。因此,它应该工作而不显式声明为全局。
如果您尝试这样做:
a = [1, 2, 3]
def test_immutable():
a = [1, 4, 3]
test_immutable()
print(a)
由于数组将在本地引用中更新,因此输出为[1, 2, 3]
。但是,如果您尝试这样做:
a = [1, 2, 3]
def test_immutable():
global a
a = [1, 4, 3]
test_immutable()
print(a)
输出将为[1, 4, 3]
,因为值正在全局引用中更新且没有任何错误。