Python 3.11 对象像槽一样轻吗?

Jor*_*uis 15 python slots python-internals python-3.11

经过Mark Shannon对Python对象的优化,普通对象和带槽的对象有什么不同吗?据我所知,在正常用例中进行此优化后,对象没有字典。新的 Python 对象是否已经完全不需要使用槽了?

use*_*ica 13

不,__slots__仍然会产生更紧凑的物体。

使用__slots__for 属性,对象的内存布局每个槽只需要一个指针。通过新的惰性__dict__创建,对象需要存储一个PyDictValues对象和一个指向该PyDictValues对象的指针。

PyDictValues对象包含基于创建对象时共享密钥对象的“可用大小”的多个PyDictValues指针的空间,这通常比您使用__slots__. 它还保存一些额外的元数据和填充,存储在这些指针之前:表示该元数据大小的“前缀大小”,表示存储值的数量的“已使用大小”,以及跟踪插入顺序的字节数组。填充用于确保这些额外的元数据不会干扰指针的对齐(这些都没有反映在PyDictValues结构定义中,因为 C 结构定义对此的表达能力不够 - 它主要必须手动处理。)

因此,如果没有__slots__,您将直接在对象中获得额外的空间,通常为属性指针分配比必要的更多的空间,并且相对于使用 ,PyDictValues *其本身还有一堆额外的元数据。PyDictValues__slots__

另外,对于__slots__,如果您没有显式声明__weakref__插槽,则不会获得插槽,从而节省了一些内存,但代价是无法创建对对象的弱引用。如果没有 no ,Python 会自动为你的对象__slots__添加一个槽。__weakref__