每个 Python 对象都有标识、类型和值。只有对象的值会不时变化。7

7其实,对象的类型也可以变,方法只有一种:为 __class__ 属性指定其他类。但这是在作恶,我后悔加上这个脚注了。

如果两个变量指代的不可变对象具有相同的值(a == bTrue),实际上它们指代的是副本还是同一个对象的别名基本没什么关系,因为不可变对象的值不会变,但有一个例外。这里说的例外是不可变的集合,如元组和 frozenset:如果不可变集合保存的是可变元素的引用,那么可变元素的值发生变化后,不可变集合也会随之改变。实际上,这种情况不是很常见。不可变集合不变的是所含对象的标识。

变量保存的是引用,这一点对 Python 编程有很多实际的影响。

在 CPython 中,对象的引用数量归零后,对象会被立即销毁。如果除了循环引用之外没有其他引用,两个对象都会被销毁。某些情况下,可能需要保存对象的引用,但不留存对象本身。例如,有一个类想要记录所有实例。这个需求可以使用弱引用实现,这是一种低层机制,是 weakref 模块中 WeakValueDictionaryWeakKeyDictionaryWeakSet 等有用的集合类,以及 finalize 函数的底层支持。