正如您之前可能已经注意到的,CPython有时会存储相同的不可变对象的单个副本。
e.g。
>>> 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
有没有办法反省解释器并打印出这个假定的不可变对象堆?
答案 0 :(得分:8)
不,实习对象在一系列位置维护,没有一种方法可以列出所有这些对象。
intern()
function自行实习。()
)是一个单例,并且每个元组大小1到20都保持缓存以便循环使用。 (只是元组对象,而不是内容)。None
是单身,Ellipsis
,NotImplemented
,True
和False
也是。__dict__
字典可以share keys保存在内存中。in
语句一起使用)和as of Python 3.2集(再次与in
一起使用时)。可能还有更多我尚未发现。
这些优化都有助于避免过多的堆流失。除了None
,Ellipsis
,NotImplemented
,True
和False
是单例之外,它们都是特定于CPython的优化,它们不是Python的一部分语言定义本身。
答案 1 :(得分:3)
这比你做到的要复杂一点。例如,在具有大整数的示例中,当使用不属于同一表达式时,同一对象不重用。
>>> a = 7734
>>> b = 7734
>>> a is b
False
另一方面,正如您的第一个示例所示,这适用于字符串...但不是所有字符串。
>>> a = "this string includes spaces"
>>> b = "this string includes spaces"
>>> a is b
False
以下对象实际上是默认实现的:小整数,空元组和看起来像Python标识符的字符串。您在大整数和其他不可变对象中看到的是一种优化,因为它们被用在同一个表达式中。