【发布时间】:2019-01-31 08:18:21
【问题描述】:
代码:
from weakref import WeakSet
se = WeakSet()
se.add(1)
输出:
TypeError: cannot create weak reference to 'int' object
Doc:
list、dict等几种内置类型不直接支持弱引用,但可以通过子类化添加支持:
...
其他内置类型,如 tuple 和 int 不支持弱引用,即使是子类化(这是一个实现细节,在不同的 Python 实现中可能会有所不同。)。
这不足以表达解释:
为什么有些内置类型不支持弱引用?
究竟哪些类型支持弱引用?
补充一些想法:
对于上面的示例,您可以将 int 包装在用户定义的包装类中,并且该包装类支持弱引用(熟悉 Java 的人会记得 int 和 Integer):
from weakref import WeakSet
se = WeakSet()
class Integer:
def __init__(self, n=0):
self.n = n
i = 1
I = Integer(1)
se.add(i) # fail
se.add(I) # ok
我不确定为什么 Python 不为常用的内置类型(int、str 等)提供自动包装,而是简单地说它们不支持弱引用。这可能是由于性能问题,但无法弱引用这些内置类型大大减少了它的使用。
【问题讨论】:
-
相关:What exactly is __weakref__ in Python?(可以说是同一个问题,但倒退了)
-
您对 C API 有任何了解吗?您是否按照链接(紧接在您引用的文档之后)到 Weak Reference Support?如果是这样,答案的第 1 部分非常简单,尽管第 2 部分仍然不是那么简单。如果不是,那就更复杂了,因为它需要解释这些文档中的大部分内容。
-
@Aran-Fey 什么是
__weakref__不是什么是weakref?这个问题没有提到内置类型。 -
@abarnert 我点击了链接,但它没有告诉你为什么内置类型不支持弱引用。您可以从该部分得出的唯一结论可能是*内置类型太简单,无法支持弱引用,但这还不够表达。
-
@Cyker 这就是为什么我说如果您阅读了第 1 部分的答案会非常简单,而不是说阅读它会给您答案。 (它告诉你如果内置类型想要成为弱引用,它们必须做什么,但你仍然需要解释他们为什么不这样做。而且,对于第 2 部分,唯一的答案是遍历每个内置类型,无论是在源代码中还是在 REPL 中,以检查哪些是这样做的。)
标签: python weak-references python-internals