每个对象都有各自的编号、类型和值。一个对象被创建后,它的 编号 就绝不会改变;你可以将其理解为该对象在内存中的地址。 '' 运算符可以比较两个对象的编号是否相同;id()
函数能返回一个代表其编号的整型数。
CPython implementation detail: 在 CPython 中,id(x)
就是存放 x
的内存的地址。
有些对象的 值 可以改变。值可以改变的对象被称为 可变的;值不可以改变的对象就被称为 不可变的。(一个不可变容器对象如果包含对可变对象的引用,当后者的值改变时,前者的值也会改变;但是该容器仍属于不可变对象,因为它所包含的对象集是不会改变的。因此,不可变并不严格等同于值不能改变,实际含义要更微妙。) 一个对象的可变性是由其类型决定的;例如,数字、字符串和元组是不可变的,而字典和列表是可变的。
对象绝不会被显式地销毁;然而,当无法访问时它们可能会被作为垃圾回收。允许具体的实现推迟垃圾回收或完全省略此机制 —- 如何实现垃圾回收是实现的质量问题,只要可访问的对象不会被回收即可。
注意:使用实现的跟踪或调试功能可能令正常情况下会被回收的对象继续存活。还要注意通过 '…' 语句捕捉异常也可能令对象保持存活。
有些对象包含对 "外部" 资源的引用,例如打开文件或窗口。当对象被作为垃圾回收时这些资源也应该会被释放,但由于垃圾回收并不确保发生,这些对象还提供了明确地释放外部资源的操作,通常为一个 close()
方法。强烈推荐在程序中显式关闭此类对象。'…finally
' 语句和 '' 语句提供了进行此种操作的更便捷方式。
类型会影响对象行为的几乎所有方面。甚至对象编号的重要性也在某种程度上受到影响: 对于不可变类型,会得出新值的运算实际上会返回对相同类型和取值的任一现有对象的引用,而对于可变类型来说这是不允许的。例如在 a = 1; b = 1
之后,a
和 可能会也可能不会指向同一个值为一的对象,这取决于具体实现,但是在 c = []; d = []
之后,c
和 d
保证会指向两个不同、单独的新建空列表。(请注意 c = d = []
则是将同一个对象赋值给 c
和 d
。)