您之前可能已经注意到,CPython 有时会存储相同不可变对象(immutable对象)的单个副本。
例如
>>> a = "hello"
>>> b = "hello"
>>> a is b
True
>>> a, b = 7734, 7734
>>> a is b
True
看来我认为是堆的散列是在类型推断之后执行的
>>> a, b = 7734, 07734
>>> a is b
False
>>> a, b = 7734, 017066
>>> a is b
True
有什么方法可以反省解释器并打印出这堆假设的不可变对象(immutable对象)吗?
请您参考如下方法:
不,驻留对象在一系列位置维护,没有一种方法可以列出所有对象。
- 正如您所发现的,字符串可以被保留,并且您可以使用
intern()function 自行保留字符串。 . - -5 到 256 之间的小整数被保留。
- 元组被重用;空元组 (
()) 是一个单例,从 1 到 20 的元组大小各有 2000 个缓存以供回收。 (只是元组对象,而不是内容)。 None是单例,Ellipsis、NotImplemented、True和False.- 从 Python 3.3 开始,实例
__dict__字典可以 share keys以节省内存。 - 编译器可以将不可变(在某些情况下,可变)源代码文字标记为常量,将它们与字节码一起存储,并在每次运行字节码时重新使用它们。这适用于字符串、数字、元组、列表(如果与
in语句一起使用)和 as of Python 3.2设置(同样,当与in一起使用时)。
可能还有更多我还没有发现。
这些优化都有助于避免过多的堆流失。除了 None、Ellipsis、NotImplemented、True 和 False 是单例之外它们都是特定于 CPython 的优化,它们不是 Python 语言定义本身的一部分。
