weakref module allows to create "weak" references to objects. It's not enough to have a weak reference to keep an objects alive - if weak references are the only references the object has, then garbage collector will remove the object and reuse the memory for other objects. However, while the object isn't deleted, a weak reference can return it even if there are no regular references to the objects.
A good example of usage of weak references is cache building. If cache contains large objects and we don't want to keep it in the memory just because there is a reference from cache, then weak refs are what we need.
For example, if you have a bunch of large images' objects, you can associate an every image with its name. Using regular refs will keep the objects alive, just because they're values in a dict. Using WeakValueDictionary from the module weakref is a good alternative. If there are no more regular refs to an image, the garbage collector will remove it and associated record will be removed from the dict as well.
WeakKeyDictionary and WeakValueDictionary use weak references inside and register callback functions to tell the dictionary when a key or a value is removed by the garbage collector. WeakSet implements a set of WeakKeyDictionary.
Finalize is a simple way to register a cleanup function, which is called when an object is removed. It's simpler than settings a callback function to a weak ref, because the module prevents the removing of finalizer.
For the most of programs these container types and finalize is all you need. Usually, we don't need to generate weak references manually - low-level functional exist for advanced uses.
Not all objects can be weakly referenced. Objects you can reference too are:
- class instances
- functions
- instance methods
- sets
- frozensets
- some file objects
- generators
- object types
- sockets
- arrays
- deques
- regular expression pattern objects
- code objects
Some builtin types like list or dict doesn't support weak references directly, but their subclasses do.
class SuperDict(dict):
pass
hero_rating = SuperDict(superman=1, batman=2, deadpool=0)
Some other builtin types doesn't support weak references neither themselves or subclasses - e.g. tuple, int
When a type has __slots__ defined, weak references aren't available until the attribute __weakref__ explicitly declared in the __slots__ list.