Python 3 中的列表范围

Scope of lists in Python 3

这可能是一个非常愚蠢的问题,但我有点不确定为什么列表在 Python 3 中的行为与其他变量在范围方面不同。在下面的代码中...

foo = 1
bar = [1,2,3,4]

def baz():
    foo += 1
    bar[0]+=1

我理解为什么 foo += 1 会抛出关于 foo 超出本地范围的错误。为什么 bar[0]+=1 不抛出同样的错误?

变量foo指向一个对象(整数)。变量 baz 指向一个对象(一个列表)。如果您尝试将 baz 重新分配给另一个对象,则会出现错误。但你不是,你只是在调用列表对象上的一个方法,任何人都可以这样做。

在 python 中,如果没有 'global' 关键字,则无法修改全局变量。这是为了清楚起见。

foo=1
def bar():
     global foo
     foo=2
bar()
#foo is now 2!

因为bar[0]+=foo修改的是列表的一个元素,而不是列表变量本身的值,所以是合法的。

当你执行代码时,你会得到

 ....
     foo += 1
 UnboundLocalError: local variable 'foo' referenced before assignment

foo += 1其实就是这样评价的。 foo = foo + 1。因此,您将 1 添加到 foo 的值并将其存储在变量 foo 中。由于发生了赋值,Python 假定 foo 是局部变量。但是,如果它是一个局部变量,在表达式 foo + 1 中,foo 的值是多少? Python 无法回答这个问题。这就是它抛出该错误的原因。

但是,当您执行 bar[0] += 1 时,Python 会像这样评估它 bar[0] = bar[0] + 1。因为,它已经知道 bar 是什么,而您只是想替换其中的第一个元素,所以它允许这样做。在最后一个例子中,我们通过 foo += 1 创建了一个名为 foo 的新局部变量,但在这里,我们只是改变了同一个对象。所以 Python 允许这样做。