从版本 3.8 开始,Python 的 documentation on weak references状态:
Several built-in types such as list and dict do not directly support weak references but can add support through subclassing.
CPython implementation detail: Other built-in types such as tuple and int do not support weak references even when subclassed.
之前已经问过which types support weak references和 why the built-in types do not support weak references ,但是为什么像 tuple
和 int
这样的内置类型不支持 CPython 中的弱引用呢?
最佳答案
内置类型不支持弱引用(也不支持动态属性)这一事实是一个实现细节。通常,不需要弱引用(和动态属性)。不支持它们可以使内置类型的数据结构更小,并且对它们的操作更有效。由于这些类型(尤其是元组和字典)在 Python 的内部实现中使用,因此值得使用性能更高的实现。
这涵盖了内置类型,但是子类呢?
当前实现弱引用的方式是每个类定义一个固定的内存偏移量,其中每个实例存储对保存其弱引用的容器的引用。可以为诸如 float 之类的有限大小对象指定此固定偏移量,因为实例的数据具有固定大小,因此弱引用指针可以放置在该数据之后的固定偏移量处。像 dict
和 list
这样的可变对象被分成两部分存储在内存中。第一部分包含与实例相关的不可变数据,包括指向保存可变数据的第二部分的指针(例如保存列表内容的数组)。由于实例数据的第一部分是固定大小的,因此还可以为这些可变类型指定弱引用指针的固定偏移量。 str
和 tuple
的问题在于它们都是不可变的且大小可变。每个实例将其所有内容存储在其单个内存块中。因此,类不可能指定对所有实例都有效的弱引用指针的固定偏移量。一开始我很困惑为什么int
不能像float
那样弱引用。然后我发现int instances in Python take up a variable amount of memory depending on the value of the integer .
可以采用不同的方式来组织数据结构,从而允许弱引用适用于内置类型或其子类,但到目前为止,这种需求还不足以产生性能影响或中断如此根本性的变化。
注意:这个答案基于 Raymond Hettinger 于 2005 年 3 月 30 日在 python-list 邮件中发表的两篇文章( here 和 here ),主题行为“对从 str 派生的类的弱引用”) 。我提供了有关日期和主题的额外详细信息,因为 python-list 邮件列表链接似乎随着时间的推移而变化,但可以通过日期和主题轻松搜索。
关于python - 为什么Python中tuple和str的子类不能支持弱引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60213902/