为什么class.__weakref__不是None,而instance.__weakref__是None?

dir*_*obs 4 python weak-references python-internals

__weakref__与弱引用有关。我了解弱引用背后的整个想法以及我可以在哪里使用它们。我唯一不明白的事情如下所述:

实例本身没有属性__weakref__,与类不同,因此实例继承 __weakref__自类,这意味着A.__weakref__应该与以下内容相同 A().__weakref__

>>> class A: pass
...
>>> A().__dict__            # Each instance starts out as an empty namespace 
{}
>>> A.__weakref__ is None; 
False
>>> A().__weakref__ is None   #But this is True!
True 
Run Code Online (Sandbox Code Playgroud)

为什么whileA.__weakref__不是while实例继承自类?Noneinstance.__weakref__None__weakref__

Mar*_*ers 5

一个类有一个__weakref__ 数据描述符属性;这就像property; 仅当您访问实例上的属性时,它才会自动绑定。弱引用的实际数据存储在 C 结构中,这是 Python 用于表示内存中的类和实例的数据结构的一部分。

因此,实例不需要自己的__weakref__属性。类描述符绑定到实例数据结构,然后 C 代码只需查找正确的 C 结构即可检索所需的信息。

访问类上的属性会生成描述符对象本身。这不是None; 它是描述符对象。在实例上,绑定属性产生弱引用。None不返回弱引用手段。

您可以通过访问对象来重新创建描述符行为A.__dict__['__weakref__'](以绕过正常的type.__getattribute__()绑定行为),然后直接调用__get__它:

>>> 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>
Run Code Online (Sandbox Code Playgroud)