从版本 3.8 开始,Python 的关于弱引用的文档 https://docs.python.org/3/library/weakref.html states:
一些内置类型(例如 list 和 dict)不直接支持弱引用,但可以通过子类化来添加支持。
CPython 实现细节:其他内置类型(例如 tuple 和 int)即使在子类化时也不支持弱引用。
之前已经问过哪些类型支持弱引用 https://stackoverflow.com/questions/52011430/python-which-types-support-weak-references and 为什么内置类型不支持弱引用 https://stackoverflow.com/questions/7711246/why-weakref-doesnt-support-built-in-types-in-python/7712764,但是为什么内置类型像tuple
and int
CPython 不支持弱引用?
内置类型不支持弱引用(也不支持动态属性)这一事实是一个实现细节。通常,不需要弱引用(和动态属性)。不支持它们可以使内置类型的数据结构更小,并且对它们的操作更有效。由于这些类型(尤其是元组和字典)在 Python 的内部实现中使用,因此值得使用性能更高的实现。
这涵盖了内置类型,但是子类呢?
当前实现弱引用的方式是每个类定义一个固定的内存偏移量,其中每个实例存储对保存其弱引用的容器的引用。可以为有限大小的对象指定此固定偏移量,例如float
因为实例的数据是固定大小的,所以弱引用指针可以放置在该数据之后的固定偏移处。可变对象,例如dict
and list
被分成两部分存储在内存中。第一部分包含与实例相关的不可变数据,包括指向保存可变数据的第二部分的指针(例如保存列表内容的数组)。由于实例数据的第一部分是固定大小的,因此还可以为这些可变类型指定弱引用指针的固定偏移量。问题在于str
and tuple
是它们都是不可变的并且大小可变。每个实例将其所有内容存储在其单个内存块中。因此,类不可能指定对所有实例都有效的弱引用指针的固定偏移量。起初我很困惑为什么int
不能像这样弱引用float
。然后我发现Python 中的 int 实例占用不同数量的内存,具体取决于整数的值 https://docs.python.org/3/library/stdtypes.html#int.bit_length.
可以采用不同的方式来组织数据结构,从而允许弱引用适用于内置类型或其子类,但到目前为止,这种需求还不足以产生性能影响或破坏这种基本类型。改变。
注意:这个答案基于两篇文章(here https://mail.python.org/pipermail/python-list/2005-March/346298.html and here https://mail.python.org/pipermail/python-list/2005-March/317712.html)由 Raymond Hettinger 于 2005 年 3 月 30 日向 python-list 邮件发送,主题行为“对派生自 str 的类的弱引用”)。我提供了有关日期和主题的额外详细信息,因为 python-list 邮件列表链接似乎随着时间的推移而变化,但可以通过日期和主题轻松搜索。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)