# Python weakref **Python weakref** provides references to objects that don't prevent garbage collection. If you hold a weak reference to an object and nothing else references it, the object is freed and the weak reference becomes invalid. Use weak references to break circular references, implement caches that don't keep objects alive, or monitor when objects are deleted. ## Example This example shows weak references breaking a circular reference that would otherwise create a memory leak. ```python # run: python3 weakref.py # description: weak references for circular reference management import weakref class Parent: def __init__(self, name): self.name = name self.children = [] def add_child(self, child): self.children.append(child) child.parent = weakref.ref(self) # weak reference to parent class Child: def __init__(self, name): self.name = name self.parent = None def parent_name(self): if self.parent is None: return "no parent" parent_obj = self.parent() # call weak ref to get object if parent_obj is None: return "parent was deleted" return parent_obj.name # Create parent and child p = Parent("Alice") c1 = Child("Bob") c2 = Child("Carol") p.add_child(c1) p.add_child(c2) print(f"c1 parent: {c1.parent_name()}") print(f"c2 parent: {c2.parent_name()}") # Delete parent; weak ref becomes invalid del p print(f"after deletion: {c1.parent_name()}") # With strong refs (circular), memory would leak # With weak refs, parent can be garbage collected ``` ## Common patterns **Creating weak references**: - `ref = weakref.ref(obj)`: create weak reference - `obj = ref()`: dereference (returns None if object was deleted) - `weakref.proxy(obj)`: returns proxy that raises ReferenceError if deleted **Callback on deletion**: - `weakref.ref(obj, callback)`: call callback when object is garbage collected - Callback receives weak reference as argument - Useful for cleanup, logging, cache invalidation **Weak value dictionaries**: - `weakref.WeakValueDictionary()`: dict that releases values when no other refs exist - Keys are strong, values are weak - Useful for caches where entries can be reclaimed **Weak key dictionaries**: - `weakref.WeakKeyDictionary()`: dict that releases entries when keys are deleted - Keys are weak, values are strong - Useful for associating data with objects that might be deleted **When to use**: - Breaking parent-child circular references - Implementing caches that shouldn't keep objects alive - Monitoring object lifetimes - Registering observers that shouldn't prevent cleanup **Limitations**: - Not all objects support weak references (int, str, list don't; custom classes do by default) - Weak references to built-in types require `__slots__` or custom `__weakref__` - Performance: dereferencing is slightly slower than strong refs