Python中对象的“可变/不可变”指其内存值能否原地修改:不可变对象(如int、str、tuple)任何修改操作都生成新对象,id()改变;可变对象(如list、dict、set)调用append()等方法后内容变但id()不变。

Python 中对象的“可变 / 不可变”指的是该对象在创建后,其**内存中存储的值能否被原地修改**。不是指变量能不能重新赋值,而是看对象自身的内容是否允许被改变而不新建对象。
关键区别:id() 是否变化
判断一个对象是否可变,最直接的方式是观察对它做“修改操作”后,id()(即内存地址)是否改变:
- 不可变对象(如 int、str、tuple):任何看似“修改”的操作(比如
s += "x"或i += 1)都会创建新对象,原对象不变,id()一定不同; - 可变对象(如 list、dict、set):调用
.append()、.update()、.add()等方法后,内容变了,但id()保持不变——它是同一个对象,只是内部状态被更新了。
常见误区:变量名 ≠ 对象
很多人混淆“给变量重新赋值”和“修改对象本身”。例如:
a = [1, 2] a = [3, 4] # 这不是修改列表,而是让 a 指向一个新列表
这跟可变性无关——无论对象可不可变,变量都能重新绑定。真正体现可变性的操作是:不改变变量名绑定关系,却改变了它所指对象的内容。比如:
随缘网络PHP企业网站管理系统V2.0正式发布,该企业网站管理系统采用PHP+MYSQL编写,界面色调风格延续之前1.0版管理系统简洁浅蓝色风格,稍有所变动。变更分类树形目录方式采用jquery库,产品,文章三级无限分类。希望大家能够喜欢。系统中难免有些小问题,希望大家在使用中有什么问题可到本站论坛提出,我们将总结各问题后给予修正并升级。本站再次声明对于免费版系列系统本站不提供QQ电话等技术咨询服
立即学习“Python免费学习笔记(深入)”;
lst = [1, 2] lst.append(3) # lst 仍指向原对象,但内容变成 [1, 2, 3],id(lst) 不变
为什么设计成这样?影响在哪?
不可变性带来安全性与一致性:
- str 和 tuple 可作字典键或集合元素,因为它们哈希值稳定;
- 函数默认参数若用可变对象(如
def f(x=[])),多次调用会共享同一列表,导致意外累积——这是典型因忽略可变性引发的 bug; - 传参时,可变对象在函数内被修改,会影响外部原始对象(所谓“传对象引用”,效果类似传指针);不可变对象则不会,因为任何“修改”都生成新对象。
如何快速查某个类型是否可变?
没有绝对的“查文档才知”,但有实用经验:
- 内置原子类型基本都不可变:
int、float、bool、str、bytes、NoneType、tuple(注意:tuple 内部可以含可变对象,但 tuple 本身结构不可变); - 容器类若提供原地修改方法(
.append()、.clear()、.pop()等),大概率可变:list、dict、set、bytearray; - 自定义类默认可变(除非手动冻结,如用
@dataclass(frozen=True)或限制__slots__并禁写逻辑)。









