A class has a __weakref__ data descriptor attribute; this acts just like a property; only when you access the attribute on an instance is it automatically bound. The actual data for a weak reference is stored in a C structure, part of the data structure Python uses to represent classes and instances in memory.
As such, instances don't need their own __weakref__ attribute. The class descriptor is bound to the instance data structure, and the C code then just looks in the right C struct to retrieve the information needed.
Accessing the attribute on the class, produces the descriptor object itself. This is not None; it is the descriptor object. On an instance, the bound attribute produces the weak reference. No weak reference means None is returned.
You can re-create the descriptor behaviour by accessing the object via A.__dict__['__weakref__'] (to bypass the normal type.__getattribute__() binding behaviour), then directly calling __get__ on that:
>>> import weakref >>> class A(object): pass ... >>> a = A() >>> A.__weakref__ <attribute '__weakref__' of 'A' objects> >>> descriptor = A.__dict__['__weakref__'] >>> descriptor.__get__(None, A) <attribute '__weakref__' of 'A' objects> >>> a = A() >>> a.__weakref__ is None True >>> descriptor.__get__(a) is None True >>> wr = weakref.ref(a) # add a weak reference >>> wr <weakref at 0x10bd86d68; to 'A' at 0x10bad3588> >>> a.__weakref__ <weakref at 0x10bd86d68; to 'A' at 0x10bad3588> >>> descriptor.__get__(a) <weakref at 0x10bd86d68; to 'A' at 0x10bad3588>
A.__weakref__is the same asA().__weakref__" - clearly not, so your assumption that "instances inherit__weakref__from the class" is incorrect.A.__weakref__ is A().__weakref__evaluates toFalse.