weakref Python
| Введение | |
| Пример | |
| Применение | |
| Похожие статьи |
Введение
Слабые ссылки позволяют обращаться к объктам если они существуют, но не предотвращают уничтожение объекта, так как не учитываются
сборщиком мусора.
Если на объект есть хотя бы одна сильная ссылка, сборщик мусора его не удалит. Даже несколько слабых ссылок не помешают удалению объекта.
Оффициальная документация
Пример
# weakref_ex.py class C: def __del__(self): print(f"bye! {self=}")
python -i weakref_ex.py
>>> C() <__main__.C object at 0x0000026988726C30>
Объект ещё не удалился из памяти
>>> _ <__main__.C object at 0x0000026988726C30>
Если ввести новую команду объект удалится
>>> 1 bye! self=<__main__.C object at 0x0000026988726C30> 1
Будем следить за числом ссылок на объект с помощью sys.getrefcount()
>>> c = C() >>> import sys >>> sys.getrefcount(c) 2 >>> d = c >>> sys.getrefcount(c) 3 >>> d = None >>> sys.getrefcount(c) 2 >>> c = None bye! self=<__main__.C object at 0x000001CA58C52790> >>> c = C() >>> sys.getrefcount(c) 2
Теперь проделаем то же самое, но с помощью weakref
>>> import weakref >>> d = weakref.ref(c) >>> sys.getrefcount(c) 2 >>> d <weakref at 0x0000026988732BB0; to 'C' at 0x000002698846B950>
Если вызвать d то мы получим либо ссылку на объект либо None
>>> d() <__main__.C object at 0x000002698846B950>
Очистим последнее выражение
>>> _ <__main__.C object at 0x000002698846B950> >>> 1 1
Присвоим c новое значение
>>> c = 5 bye! self=<__main__.C object at 0x000002698846B950>
Убедимся, что теперь d() вернёт None. Чтобы не чистить за собой последнее выражение воспользуемся print()
>>> print(d()) None
РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе
Конец рекламы. Если там пусто считайте это рекламой моей телеги
Применение
weakref может быть полезен при кэшировании.
>>> dct = weakref.WeakKeyDictionary()
>>>
>>> c = C()
>>>
>>> dct[c] = 2
>>>
>>> dct[c]
2
>>> dct.items()
Также с его помощью можно ускорить сборщик мусора
>>> c = C() >>> c.c = c >>> c.c.c.c.c.c.c <__main__.C object at 0x000001E4629B6C60> >>> 1 1 >>> c = None >>> >>>
Объект не удалён сборщиком мусора. Нужно вызывать его явно
>>> import gc >>> gc.collect() bye! self=<__main__.C object at 0x000001E4629B6C60> 1
То же самое но с weakref.proxy
>>> c = C() >>> c.x = 1 >>> c.x 1 >>> import weakref >>> c.c = weakref.proxy(c) >>> c.c.c.c.c.c.c <weakproxy at 0x000001E4629ED940 to C at 0x000001E4626FB950> >>> c.c.c.c.c.c.x 1 >>> c = None bye! self=<__main__.C object at 0x000001E4626FB950> >>>
Объект удалён автоматически
Автор статьи: Андрей Олегович
| Размер объекта | |
| weakref | |
| Основы Python | |
| Встроенные типы данных | |
| Изменяемые и неизменяемые | |
| Итерация | |
| os | |
| dir() | |
| id() |
РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе
Конец рекламы. Если там пусто считайте это рекламой моей телеги