Weakref и __slots__

Рассмотрим следующий код:

from weakref import ref

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

k = Klass()
r = ref(k)

он работает, но когда я раскомментирую __slots__, он разбивается на TypeError: "cannot create weak reference to 'Klass' object" под Python 2.6.

Пожалуйста, кто-нибудь знает, является ли это неотъемлемым ограничением Python и __slots__, или если это ошибка? Как обойти это?

Ответ 1

Без переменной __weakref__ для каждого экземпляра классы, определяющие __slots__, не поддерживают слабые ссылки на свои экземпляры. Если необходима слабая опорная поддержка, добавьте __weakref__ в последовательность строк в объявлении __slots__.

Из Документация Python.

Если вы добавите __weakref__ в __slots__, ваш код будет работать:

>>> 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

Вам нужно добавить __weakref__ в список слотов. Это один из __slots__ quirks. До 2.3, даже это не сработало, но, к счастью, ваша версия не так уж и старая.