Python 列表(和其他对象)在函数内索引时发生变化

Python list (and other objects) change when indexed inside a function

我对 Python 的(有限)理解是,即使在函数内部进行了修改,在函数外部定义的对象也应保持不变,即

def fun():
    i=1
    return('done')

i=0
fun()
i==0 ## True

但是,列表(和其他对象,如 numpy 数组)在函数内部索引时会发生变化:

def fun():
    img[0] = img[0] + 100 
    return('done')

img = [0, 1]
fun()
img == [0, 1] ## False

很明显,我遗漏了一个关于如何在函数内部处理全局变量和局部变量的核心概念,但似乎无法在网上找到任何信息。有人可以解释为什么索引时对象在函数内部发生变化吗?另外,有人可以描述如何避免这个“特性”,这样当我在函数内索引对象(列表、数组等)时,我不会无意中更改在该函数外定义的对象吗?谢谢!

请查看我最近对一个密切相关问题的回答:

您的示例涉及两个概念:

  1. 赋值与引用的行为
  2. 改变单个容器对象

对于项目 (1.) 当 fun 分配 i = 1 时, 它创建一个新的局部变量 由于缺少 global 声明。

对于第 (2.) 项,让我们考虑一下这个稍微简单一些的代码, 因为它没有改变本质问题:

    img[0] = 100 

赋值运算符定位img 首先咨询函数的本地范围(未找到) 然后在模块的全局范围内找到它。 参考现有的 img 对象, 然后调用 __setitem__ 改变第零个元素指向的内容。 在这种情况下,它将指向一个不可变的 int 对象。 setter 的赋值是由 STORE_SUBSCR 字节码指令执行的。