繁体   English   中英

可变范围,不可变 vs 可变,就 += 而言

[英]Variable scope, immutable vs mutable, in terms of +=

这是在第一次使用后重新分配时对局部变量的 UnboundLocalError的后续问题。

case-1,下面的代码

a = 0
def test_immutable():
    a += 1
test_immutable()

遇到错误:

UnboundLocalError: local variable 'a' referenced before assignment

对原帖的回答很好地解释了第一个案例。 a += 1进行赋值,因此创建a一个尚未分配给任何对象的局部变量,因此引用它会导致UnboundLocalError

当我在下面的第二个示例中用array[0]替换a时,它在没有UnboundLocalError情况下UnboundLocalError

case-2,下面的代码

array = [0, 0, 0]
def test_mutable():
    array[0] += 1
test_mutable()
print(array)

产出

[1, 0, 0]

我猜它是与a不可变的,而array是可变的。 但是 Python 究竟是如何区别对待这两种情况的呢? 我糊涂了。

您正在观察的问题与可变或不可变类型实际上没有任何关系,这是一个范围问题。

考虑以下:

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供本地使用,而是继续使用全局array

当全局变量在像您这样的函数中更新时,应该明确声明为全局变量,这会正常工作。

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]因为值正在全局引用中更新并且没有任何错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM