弱引用和 __slots__

22

请考虑以下代码:

from weakref import ref

class Klass(object):
    # __slots__ = ['foo']
    def __init__(self):
        self.foo = 'bar'

k = Klass()
r = ref(k)

当我取消注释__slots__时,它能够正常工作。但在Python 2.6下会出现TypeError: "cannot create weak reference to 'Klass' object"错误。

请问有人知道这是Python和__slots__的固有限制还是一个bug?如何解决这个问题?

2个回答

29

如果每个实例没有一个__weakref__变量,定义__slots__的类将不支持对其实例的弱引用。如果需要支持弱引用,则在__slots__声明中添加__weakref__字符串序列。

来自Python文档

如果在__slots__中添加__weakref__,你的代码将可以工作:

>>> from weakref import ref
>>>
>>> class Klass(object):
>>>     __slots__ = ['foo', '__weakref__']
>>>     def __init__(self):
>>>         self.foo = 'bar'
>>> k = Klass()
>>> k
 => <__main__.Klass object at ...>
>>> r = ref(k)
>>> r
 => <weakref at ...; to 'Klass' at ...>

2
这是一个很好的答案,但我无法在谷歌上找到它。为了改善其索引,我引用了在创建对具有__slots__的对象的引用时出现的确切问题的错误消息:TypeError: cannot create weak reference to given object。它发生在Python 2.7、3.5、3.6、3.7中,但有趣的是,在pypy和pypy3中却没有发生。 - Mikaelblomkvistsson

9
你需要将__weakref__添加到slots列表中。这是__slots__的奇怪行为之一。在2.3版本之前,即使这样也不起作用,但幸运的是你的版本不是那么旧。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接