Python中对象的“可变/不可变”指其内存值能否原地修改:不可变对象(如int、str、tuple)任何修改操作都生成新对象,id()改变;可变对象(如list、dict、set)调用append()等方法后内容变但id()不变。
Python 中对象的“可变 / 不可变”指的是该对象在创建后,其**内存中存储的值能否被原地修改**。不是指变量能不能重新赋值,而是看对象自身的内容是否允许被改变而不新建对象。
判断一个对象是否可变,最直接的方式是观察对它做“修改操作”后,id()(即内存地址)是否改变:
s += "x" 或 i += 1)都会创建新对象,原对象不变,id() 一定不同;
.append()、.update()、.add() 等方法后,内容变了,但 id() 保持不变——它是同一个对象,只是内部状态被更新了。很多人混淆“给变量重新赋值”和“修改对象本身”。例如:
a = [1, 2] a = [3, 4] # 这不是修改列表,而是让 a 指向一个新列表
这跟可变性无关——无论对象可不可变,变量都能重新绑定。真正体现可变性的操作是:不改变变量名绑定关系,却改变了它所指对象的内容。比如:
lst = [1, 2] lst.append(3) # lst 仍指向原对象,但内容变成 [1, 2, 3],id(lst) 不变
不可变性带来安全性与一致性:
def f(x=[])),多次调用会共享同一列表,导致意外累积——这是典型因忽略可变性引发的 bug;没有绝对的“查文档才知”,但有实用经验:
int、float、bool、str、bytes、NoneType、tuple(注意:tuple 内部可以含可变对象,但 tuple 本身结构不可变);.append()、.clear()、.pop() 等),大概率可变:list、dict、set、bytearray;@dataclass(frozen=True) 或限制 __slots__ 并禁写逻辑)。