Python › Descriptors & Properties

How would you use a WeakKeyDictionary inside a descriptor to store per-instance data without relying on the instance's own __dict__ or requiring a dedicated __slots__ entry?

Advanced

Answer

Store {instance: value} pairs in a weakref.WeakKeyDictionary INSIDE the descriptor object itself (not the instance) — WeakKeyDictionary automatically removes entries once the corresponding instance is garbage collected, avoiding both the __slots__ storage problem AND any risk of the descriptor's cache keeping instances alive forever (a memory leak).
import weakref

class Cached:
    def __init__(self):
        self.data = weakref.WeakKeyDictionary()
    def __get__(self, instance, owner):
        if instance is None:
            return self
        return self.data.get(instance)
    def __set__(self, instance, value):
        self.data[instance] = value
Real-world example Building a descriptor that works correctly even on classes using __slots__, without leaking memory by keeping instances alive indefinitely.

Common follow-ups: Why is a REGULAR dictionary (not WeakKeyDictionary) risky to use for this same purpose, in terms of memory leaks?