Weak References with weakref
Sveip for å vise menyen
A normal reference keeps an object alive by incrementing its reference count. A weak reference points to an object without incrementing its count – the object can be garbage collected even while a weak reference to it exists. This is the standard tool for caches and observer patterns where you don't want references to prevent cleanup.
The Problem Weak References Solve
A cache that holds strong references to its values keeps those values alive indefinitely – even if nothing else in the program needs them:
12345678910111213141516171819202122232425import sys # Strong reference cache – objects never collected while in cache class ReportCache: def __init__(self): self._cache = {} def store(self, key, value): self._cache[key] = value # Strong reference – keeps value alive def get(self, key): return self._cache.get(key) cache = ReportCache() class Report: def __init__(self, report_id): self.report_id = report_id report = Report("Q1") cache.store("Q1", report) del report # Object NOT collected – cache still holds a strong reference print(cache.get("Q1")) # Still accessible print(sys.getrefcount(cache.get("Q1"))) # Count > 1
Using weakref.ref()
A weak reference does not prevent garbage collection. When the object is collected, the weak reference returns None:
123456789101112131415161718import weakref class Report: def __init__(self, report_id): self.report_id = report_id def __repr__(self): return f"Report({self.report_id})" report = Report("Q2") weak = weakref.ref(report) # Creating a weak reference print(weak()) # Report(Q2) – object still alive print(weak() is report) # True del report # Last strong reference removed – object collected print(weak()) # None – object has been garbage collected
weakref.WeakValueDictionary — Automatic Cache Cleanup
WeakValueDictionary stores values as weak references. Entries are removed automatically when their values are garbage collected:
1234567891011121314151617181920212223import weakref class DataSet: def __init__(self, dataset_id): self.dataset_id = dataset_id def __repr__(self): return f"DataSet({self.dataset_id})" # Cache that doesn't prevent garbage collection of its values cache = weakref.WeakValueDictionary() dataset_a = DataSet("sales_2024") dataset_b = DataSet("costs_2024") cache["sales"] = dataset_a cache["costs"] = dataset_b print(dict(cache)) # Both entries present del dataset_a # Strong reference removed – entry auto-removed from cache print(dict(cache)) # Only 'costs' remains
weakref.WeakSet — Tracking Objects Without Owning Them
WeakSet stores objects as weak references – useful for observer registries where observers should not be kept alive by the registry itself:
1234567891011121314151617181920212223import weakref class EventListener: def __init__(self, name): self.name = name def on_event(self, event): print(f"{self.name} received: {event}") # Registry that doesn't prevent listeners from being collected listener_registry = weakref.WeakSet() listener_a = EventListener("dashboard") listener_b = EventListener("logger") listener_registry.add(listener_a) listener_registry.add(listener_b) print(f"Active listeners: {len(listener_registry)}") # 2 del listener_a # Removed from registry automatically print(f"Active listeners: {len(listener_registry)}") # 1
When to Use Weak References
Use weak references when:
- Building a cache that should release values when memory is needed;
- Implementing an observer or event system where listeners shouldn't be kept alive by the dispatcher;
- Tracking objects without claiming ownership of their lifetime.
Do not use them for objects that must stay alive for the duration of the program.
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår