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() >>> list(dct.items()) [(<__main__.C object at 0x000001E4626FB950>, 2)] >>> 1 1 >>> c = None bye! self=<__main__.C object at 0x000001E4626FB950> >>> >>> print(list(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()

РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе

Конец рекламы. Если там пусто считайте это рекламой моей телеги

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: