переменная __weakref__
- это атрибут, который позволяет объекту поддерживать слабые ссылки и сохранять слабые ссылки на объект.
Как упоминалось питон документация объяснил weakref
here:
когда только остальные ссылки на референта слабые ссылки, сбор мусора бесплатно уничтожить референта и повторно использовать его память для чего-то еще.
Таким образом, обязанность слабых ссылок обеспечивает условия для объекта, чтобы иметь возможность собирать мусор независимо от его типа и объема.
И о __slots__
документации объясняет их очень хорошо:
По умолчанию экземпляры классов имеют словарь для хранения атрибутов. Это освобождает пространство для объектов, имеющих очень мало переменных экземпляра. Распространение пространства может стать острой при создании большого количества экземпляров.
Значение по умолчанию может быть переопределено путем определения __slots__
в определении класса. Объявление __slots__
принимает последовательность переменных экземпляра и резервирует достаточно места в каждом экземпляре для хранения значения для каждой переменной. Пробел сохраняется, потому что для каждого экземпляра не создается __dict__
.
Таким образом, с помощью __slots__
вы будете управлять требуемым для хранения характеристики, он на самом деле предотвращает автоматическое создание __dict__
и __weakref__
для каждого экземпляра. Который __weakref__
является необходимой переменной каждого объекта, чтобы иметь возможность справляться со слабыми ссылками.
В документации для object.__slots__
класса говорит:
Эта переменная класса может быть присвоена строка, итерацию или последовательность строк с именами переменных, используемых экземплярами. __slots__
резервирует место для объявленных переменных и предотвращает автоматическое создание __dict__
и __weakref__
для каждого экземпляра.
В двух словах, история в том, что __slots__
предназначены для управления распределением памяти вручную, а с __weakref__
является лицензия принимать слабые ссылки на объекты, которые связаны с хранением (из-за способности сборщиком собрано), поэтому __slots__
будет управлять __weakref__
, а также управлять атрибутом __dict__
.
Также документация показал вам способ сделать объект для поддержки слабых ссылок вдоль стороны с помощью __slots__
:
Без __weakref__
переменной для каждого экземпляра, классы, определяющие __slots__
не поддерживают слабые ссылки на его экземпляров. Если необходима слабая опорная поддержка, добавьте '__weakref__'
в последовательность строк в объявлении __slots__
.
Вот пример в питона 3.X:
>>> class Test:
... __slots__ = ['a', 'b']
...
>>>
>>> import weakref
>>>
>>> t = Test()
>>>
>>> r = weakref.ref(t)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create weak reference to 'Test' object
>>>
>>> class Test:
... __slots__ = ['a', 'b', '__weakref__']
...
>>> t = Test()
>>> r = weakref.ref(t)
>>>
>>> t.__weakref__
<weakref at 0x7f735bc55d68; to 'Test' at 0x7f735bc51fc8>
Но в Python 2.7 там, хотя документация, как вышеупомянутые документы, создавая слабую ссылку из экземпляров, которые не обеспечивают __weakref__
переменной в их __slots__
имен, не приподнять TypeError
:
>>> class Test:
... __slots__ = ['a', 'b']
...
>>> t = Test()
>>>
>>> r = weakref.ref(t)
>>>
>>> r
<weakref at 0x7fe49f4185d0; to 'instance' at 0x7fe4a3e75f80>
Я ничего не вижу в кавычках документов о том, что на самом деле делает '__weakref__' (в нем содержится слабый опорный синглтон). Позаботьтесь об этом? – dhke
@dhke: То же самое здесь ... Понятие слабых ссылок ясно, я действительно задумываюсь о точном значении и функции '__weakref__'. Я подозреваю, что это возможно настолько тривиально, что они просто опустили его ... – Michael
Учитывая ваше редактирование и последнее предложение в сообщении: '__weakref__' - это всего лишь флаг, который гласит:« Да, я могу слабо ссылаться ». (?) – Michael