【问题标题】:Why can't subclasses of tuple and str support weak references in Python?为什么 tuple 和 str 的子类在 Python 中不能支持弱引用?
【发布时间】:2020-02-13 17:58:27
【问题描述】:
【问题讨论】:
标签:
python
weak-references
cpython
【解决方案1】:
内置类型不支持弱引用(也不支持动态属性)这一事实是一个实现细节。通常,不需要弱引用(和动态属性)。不支持它们允许内置类型的数据结构更小,并且对它们的操作更有效。由于这些类型(尤其是元组和字典)在 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),主题为“Weakrefs to classes that derived from str”) .我提供了有关日期和主题的额外详细信息,因为 python-list 邮件列表链接似乎会随着时间而变化,但可以按日期和主题轻松搜索。