【问题标题】:Why is class.__weakref__ not None, while instance.__weakref__ is None?为什么 class.__weakref__ 不是 None,而 instance.__weakref__ 是 None?
【发布时间】:2016-04-24 20:32:56
【问题描述】:

__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 

为什么A.__weakref__ 不是Noneinstance.__weakref__None 尽管实例从类继承__weakref__

【问题讨论】:

  • "这意味着 A.__weakref__A().__weakref__" 相同 - 显然不是,所以您假设 "instances 从类继承 __weakref__ " 不正确。 A.__weakref__ is A().__weakref__ 计算结果为 False

标签: python weak-references python-internals


【解决方案1】:

一个类有一个__weakref__data descriptor attribute;这就像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>

【讨论】:

    猜你喜欢
    • 2016-08-15
    • 2011-10-19
    • 2012-09-29
    • 2013-07-15
    • 2019-05-08
    • 2021-03-21
    • 2011-11-10
    • 2013-12-25
    • 2020-10-17
    相关资源
    最近更新 更多