weakref
The weakref module provides tools for creating weak references to objects. A weak reference does not prevent the referenced object from being garbage collected. When an object only has weak references, Python’s garbage collector can reclaim its memory. This is useful for caches, observer patterns, and avoiding circular reference memory leaks.
Functions
ref()
Creates a weak reference to an object. The returned reference object is callable. Calling it returns the referenced object, or None if the object has been garbage collected.
weakref.ref(object[, callback])
| Parameter | Type | Default | Description |
|---|---|---|---|
object | object | — | The object to reference weakly |
callback | callable | None | Called when the referenced object is garbage collected |
Returns: weakref.ref object
Example:
import weakref
class MyClass:
pass
obj = MyClass()
r = weakref.ref(obj)
print(r()) # <__main__.MyClass object at 0x...>
del obj
print(r()) # None
proxy()
Creates a weak reference proxy. This is like a weak reference, but behaves like the original object. Accessing a dead proxy raises ReferenceError.
weakref.proxy(object[, callback])
| Parameter | Type | Default | Description |
|---|---|---|---|
object | object | — | The object to proxy weakly |
callback | callable | None | Called when the referenced object is garbage collected |
Returns: weakref.proxy object
Example:
import weakref
class MyClass:
def method(self):
return "alive"
obj = MyClass()
p = weakref.proxy(obj)
print(p.method()) # alive
del obj
# p.method() # raises ReferenceError
getweakrefcount()
Returns the number of weak references to an object.
weakref.getweakrefcount(object)
| Parameter | Type | Default | Description |
|---|---|---|---|
object | object | — | The object to query |
Returns: int
Example:
import weakref
obj = object()
r1 = weakref.ref(obj)
r2 = weakref.ref(obj)
print(weakref.getweakrefcount(obj)) # 2
getweakrefs()
Returns a list of all weak references to an object that are still alive.
weakref.getweakrefs(object)
| Parameter | Type | Default | Description |
|---|---|---|---|
object | object | — | The object to query |
Returns: list of weak reference objects
Example:
import weakref
obj = object()
r1 = weakref.ref(obj)
r2 = weakref.ref(obj)
refs = weakref.getweakrefs(obj)
print(len(refs)) # 2
finalize()
Registers a finalizer to be called when an object is garbage collected. Returns a finalize object with an alive property and an atexit parameter.
weakref.finalize(obj, func, *args, **kwargs)
| Parameter | Type | Default | Description |
|---|---|---|---|
obj | object | — | The object to finalize |
func | callable | — | Function to call when obj is garbage collected |
*args | tuple | () | Arguments passed to func |
**kwargs | dict | {} | Keyword arguments passed to func |
Returns: weakref.finalize object
Example:
import weakref
class Resource:
def __init__(self, name):
self.name = name
def cleanup(self):
print(f"Cleaning up {self.name}")
resource = Resource("file")
f = weakref.finalize(resource, resource.cleanup)
del resource # prints "Cleaning up file"
Specialized Dictionaries and Sets
WeakValueDictionary
A dictionary that holds weak references to values. When the values are garbage collected, the keys are removed automatically.
weakref.WeakValueDictionary([dict])
Example:
import weakref
class ExpensiveObject:
def __init__(self, name):
self.name = name
cache = weakref.WeakValueDictionary()
obj = ExpensiveObject("big data")
cache["key"] = obj
print(cache["key"]) # <__main__.ExpensiveObject object at ...>
del obj
print("key" in cache) # False
WeakKeyDictionary
A dictionary that holds weak references to keys. When the keys are garbage collected, the entries are removed automatically.
weakref.WeakKeyDictionary([dict])
Example:
import weakref
class Key:
def __init__(self, name):
self.name = name
key = Key("unique")
d = weakref.WeakKeyDictionary()
d[key] = "value"
print(d[key]) # value
del key
print(len(d)) # 0
WeakSet
A set that holds weak references to elements. When elements are garbage collected, they are removed from the set.
weakref.WeakSet([iterable])
Example:
import weakref
class Element:
pass
e1 = Element()
e2 = Element()
s = weakref.WeakSet([e1, e2])
print(len(s)) # 2
del e1
print(len(s)) # 1
Common Patterns
Cache with WeakValueDictionary
Use WeakValueDictionary to implement a cache that automatically evicts entries when the cached objects are no longer used elsewhere.
import weakref
class Cache:
def __init__(self):
self._cache = weakref.WeakValueDictionary()
def get(self, key):
return self._cache.get(key)
def set(self, key, value):
self._cache[key] = value
Observer Pattern with WeakSet
Use WeakSet to hold observers, preventing memory leaks when observers are deleted.
import weakref
class Subject:
def __init__(self):
self._observers = weakref.WeakSet()
def attach(self, observer):
self._observers.add(observer)
def notify(self, event):
for observer in self._observers:
observer.update(event)
Errors
ReferenceError: Raised when accessing a dead proxy.TypeError: Raised when trying to create a weak reference to an immutable type (e.g.,int,str,tuple) that does not support weak references.