Слабая ссылка — это специальный тип ссылки на объект, который не увеличивает счетчик ссылок этого объекта. Это позволяет объекту быть удаленным сборщиком мусора, если на него остаются только слабые ссылки.
import weakref
class ExpensiveObject:
def __del__(self):
print("Удаление ExpensiveObject")
obj = ExpensiveObject()
r = weakref.ref(obj) # Создаем слабую ссылку
print(r()) # Доступ к объекту: <__main__.ExpensiveObject object at ...>
del obj # Удаляем сильную ссылку
print(r()) # Теперь возвращает None
import weakref
class Data:
def __init__(self, value):
self.value = value
# Обычный словарь (удерживает объекты)
regular_dict = {}
# Словарь со слабыми значениями
weak_dict = weakref.WeakValueDictionary()
data = Data(42)
regular_dict['key'] = data
weak_dict['key'] = data
del data
print(regular_dict) # {'key': <__main__.Data object>} - объект сохраняется
print(weak_dict.get('key')) # None - объект удален
weak_key_dict = weakref.WeakKeyDictionary()
key = Data(100)
weak_key_dict[key] = "some value"
print(weak_key_dict[key]) # "some value"
del key
print(list(weak_key_dict.keys())) # [] - ключ удален
weak_set = weakref.WeakSet()
element = Data(200)
weak_set.add(element)
print(len(weak_set)) # 1
del element
print(len(weak_set)) # 0
import weakref
class Node:
def __init__(self, value):
self.value = value
self._parent = None
self.children = weakref.WeakSet() # Слабые ссылки на детей
@property
def parent(self):
return self._parent() if self._parent else None
@parent.setter
def parent(self, node):
self._parent = weakref.ref(node)
node.children.add(self)
import weakref
class ImageCache:
def __init__(self):
self._cache = weakref.WeakValueDictionary()
def get_image(self, path):
if path not in self._cache:
img = self._load_image(path)
self._cache[path] = img
return self._cache[path]
obj = Data(300)
r = weakref.ref(obj)
if r() is not None: # Проверка, что объект еще существует
print("Объект жив")
else:
print("Объект удален")
weakref.ref
, WeakValueDictionary
, WeakKeyDictionary
, WeakSet
Слабые ссылки — это мощный инструмент для управления памятью в Python, особенно полезный при работе с сложными структурами данных и кэшированием.