为什么 python 列表在函数范围之外持续存在,而整数却没有?

Why do python lists persist outside function scope while integers don't?

Python 有效,这样我就可以在每次函数运行时就地更新 list

list_obj = list()
def increase_list_obj(list_obj, n):
    list_obj.append(n)

print(list_obj)
for n in range(3):
    increase_list_obj(list_obj, n)
    print(list_obj)

OUTPUT:

[]
[0]
[0, 1]
[0, 1, 2]

根据 list 的持续存在方式,我希望我也可以在每次函数运行时就地更新 int

int_obj = 0
def increase_int_obj(int_obj):
    int_obj += 1

print(int_obj)
for n in range(3):
    increase_int_obj(int_obj)
    print(int_obj)

OUTPUT:
0
0
0
0

EXPECTED:
0
1
2
3

为什么 int 更新的工作方式与 list 更新不同? 这两个对象的持久性和作用域规则有何不同?

(我并不是想建议两者应该表现相同,我很好奇为什么他们不这样做)

抢占有关如何更新 int 的答案:我知道您可以通过从函数返回值来更新 int 值:

int_obj = 0
def increase_int_obj_v2(int_obj):
    int_obj += 1
    return int_obj

print(int_obj)
for n in range(3):
    int_obj = increase_int_obj_v2(int_obj)
    print(int_obj)

OUTPUT:
0
1
2
3

谢谢!

如果函数内有赋值,则变量是局部的,否则它们是全局的:

 i += 1

是一个作业 (i = i + 1)!因此 i 是函数内的局部变量。

list_obj.append(n)

突变!因此 list_obj 在封闭的命名空间中查找,它是全局命名空间。

旁注:+= 可以是可变类型的突变:list_obj += [n] 也是突变。

为了更好地理解,您需要了解一些概念

int 是不可变的,list 是可变的

可变和不可变对象列表 可变的内置类型对象是:

  • 列表
  • 词典
  • 用户定义类

不可变的内置类型对象是:

  • 数字(整数、有理数、浮点数、小数、复数和布尔值)
  • 字符串
  • 元组
  • 冰雪奇缘套装
  • User-Defined 类(完全由用户定义特性)

什么意思?

有关不可变和可变的更多信息,请阅读 this

一些对象通过引用传递给函数,一些对象通过值传递 (more)

Python 中的对象可以从任何范围修改。关于整数的事情是它们是不可变的对象,所以每当它们被修改时,它们都会为自己制作一个新副本,该副本只存在于它创建的范围内。

另一方面,列表与大多数其他 Python 对象一样,将在适当的位置进行修改,以允许进行更改,而不管当前范围如何。

这是一个使用自定义对象的示例。

class HoldInt:
  def __init__(self, integer):
    self.integer = integer

int_obj = HoldInt(0)

def modify_int():
  int_obj.integer += 1

print(int_obj.integer)
modify_int()
print(int_obj.integer)
0
1