Michael Michael - 7 months ago 7
Python Question

What exactly is __weakref__ in Python?

Surprisingly, there's no explicit documentation for

__weakref__
. Weak references are explained here.
__weakref__
is also shortly mentioned in the documentation of
__slots__
. But I could not find anything about
__weakref__
itself.

What exactly is
__weakref__
?
- Is it just a member acting as a flag: If present, the object may be weakly-referenced?
- Or is it a function/variable that can be overridden/assigned to get a desired behavior? How?

Answer

Interestingly enough, the official documentation is somewhat non-enlightening on this topic:

Without a __weakref__ variable for each instance, classes defining __slots__ do not support weak references to its instances. If weak reference support is needed, then add __weakref__ to the sequence of strings in the __slots__ declaration.

The type object documentation on the topic does not seem to help things along too much:

When a type’s __slots__ declaration contains a slot named __weakref__, that slot becomes the weak reference list head for instances of the type, and the slot’s offset is stored in the type’s tp_weaklistoffset.

Ah, yeah. I must admit, I don't get it.

Empirically:

When you first use weakref.ref(), the target object gets its __weakref__ attribute set to an instance of weakref.weakref.

__weakref__ is the single available weak reference for an object i.e. every weak reference to the same object is equal to obj.__weakref__:

# a = A()
# b = weakref.ref(a)
# c = weakref.ref(b)
# print(b is c is a.__weakref__)
True

The role is somewhat obvious: When the garbage collector wants to collect an object, it must eliminate all weak refs from the list of references keeping the object alive. So we need to have a path obj -> weakref and that is provided by __weakref__.

I cannot find any piece of official documentation where this role of __weakref__ is actually explained properly.

Comments