python - 为什么Python中tuple和str的子类不能支持弱引用?

标签 python weak-references cpython

从版本 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 referenceswhy the built-in types do not support weak references ,但是为什么像 tupleint 这样的内置类型不支持 CPython 中的弱引用呢?

最佳答案

内置类型不支持弱引用(也不支持动态属性)这一事实是一个实现细节。通常,不需要弱引用(和动态属性)。不支持它们可以使内置类型的数据结构更小,并且对它们的操作更有效。由于这些类型(尤其是元组和字典)在 Python 的内部实现中使用,因此值得使用性能更高的实现。

这涵盖了内置类型,但是子类呢?

当前实现弱引用的方式是每个类定义一个固定的内存偏移量,其中每个实例存储对保存其弱引用的容器的引用。可以为诸如 float 之类的有限大小对象指定此固定偏移量,因为实例的数据具有固定大小,因此弱引用指针可以放置在该数据之后的固定偏移量处。像 dictlist 这样的可变对象被分成两部分存储在内存中。第一部分包含与实例相关的不可变数据,包括指向保存可变数据的第二部分的指针(例如保存列表内容的数组)。由于实例数据的第一部分是固定大小的,因此还可以为这些可变类型指定弱引用指针的固定偏移量。 strtuple 的问题在于它们都是不可变的且大小可变。每个实例将其所有内容存储在其单个内存块中。因此,类不可能指定对所有实例都有效的弱引用指针的固定偏移量。一开始我很困惑为什么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 邮件中发表的两篇文章( herehere ),主题行为“对从 str 派生的类的弱引用”) 。我提供了有关日期和主题的额外详细信息,因为 python-list 邮件列表链接似乎随着时间的推移而变化,但可以通过日期和主题轻松搜索。

关于python - 为什么Python中tuple和str的子类不能支持弱引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60213902/

相关文章:

python - AttributeError : 'IntegrityError' object has no attribute 'message' SQLAlchemy

python - SimpleGui 输入变量

python - 为什么在使用 __slots__ 时 __weakref__ 默认被移除?

python - 编译官方文档 "Embedding Python in Another Application"示例失败

python - 具有 Python C 扩展的类(不是方法)的完整和最小示例?

Python 在 Linux 上通过 pip 找不到已安装的包

python - 这个 pywinauto 异常从哪里获取它的列表?

java - 一个集合中的强引用和弱引用

c# - 对象完成但尚未收集垃圾时的弱引用行为

python - 为什么 `len(l) != 0` 在 CPython 中比 `bool(l)` 快?