gpt4 book ai didi

python - Python 类的 __dict__.__dict__ 属性是什么?

转载 作者:IT老高 更新时间:2023-10-28 21:32:29 30 4
gpt4 key购买 nike

>>> class A(object): pass
...
>>> A.__dict__
<dictproxy object at 0x173ef30>
>>> A.__dict__.__dict__
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
AttributeError: 'dictproxy' object has no attribute '__dict__'
>>> A.__dict__.copy()
{'__dict__': <attribute '__dict__' of 'A' objects> ... }
>>> A.__dict__['__dict__']
<attribute '__dict__' of 'A' objects> # What is this object?

如果我这样做 A.something = 10 , 这进入 A.__dict__ .什么 <attribute '__dict__' of 'A' objects>A.__dict__.__dict__ 中找到,它什么时候包含一些东西?

最佳答案

首先A.__dict__.__dict__不同于 A.__dict__['__dict__'] .前者不存在,后者是__dict__类的实例将具有的属性。它是一个数据描述符对象,返回特定实例的内部属性字典。总之,__dict__对象的属性不能存储在对象的 __dict__ 中,因此可以通过类中定义的描述符访问它。
要理解这一点,您必须阅读 documentation of the descriptor protocol .
简短版本:

  • 例如a类(class)A , 访问 a.__dict__A.__dict__['__dict__'] 提供与 vars(A)['__dict__'] 相同.
  • 对于一个类(class) A , 访问 A.__dict__type.__dict__['__dict__'] 提供(理论上)与 vars(type)['__dict__'] 相同.

  • 长版:
    类和对象都通过属性运算符(通过类或元类的 __getattribute__ 实现)和 __dict__ 提供对属性的访问。 vars(ob) 使用的属性/协议(protocol).
    对于普通物体, __dict__对象创建一个单独的 dict存储属性的对象,以及 __getattribute__首先尝试访问它并从那里获取属性(在尝试使用描述符协议(protocol)在类中查找属性之前,以及在调用 __getattr__ 之前)。 __dict__类上的描述符实现了对这个字典的访问。
  • a.name相当于按顺序尝试:type(a).__dict__['name'].__get__(a, type(a)) (仅当 type(a).__dict__['name'] 是数据描述符时),a.__dict__['name'] , type(a).__dict__['name'].__get__(a, type(a)) , type(a).__dict__['name'] .
  • a.__dict__做同样的事情,但出于明显的原因跳过了第二步。

  • 因为这是不可能的 __dict__对于要存储在自身中的实例,它直接通过描述符协议(protocol)访问,并存储在实例的特殊字段中。
    类似的情况也适用于类,尽管它们的 __dict__是一个特殊的代理对象,它伪装成一个字典(但可能不是内部的),并且不允许您更改它或将其替换为另一个。除其他外,此代理允许您访问特定于它的类的属性,而不是在其基类之一中定义的。
    默认情况下,一个 vars(cls)一个空类携带三个描述符: __dict__用于存储实例的属性, __weakref__weakref 内部使用, 和 __doc__类的文档字符串。如果您定义 __slots__,前两个可能会消失。 .那么你就没有 __dict____weakref__属性,但相反,每个插槽都有一个类属性。实例的属性不会存储在字典中,并且对它们的访问将由类中的相应描述符提供。

    最后, A.__dict__ 的不一致不同于 A.__dict__['__dict__']是因为属性 __dict__作为异常(exception),从未在 vars(A) 中查找过,所以它的真实性对于您使用的几乎任何其他属性都不是真实的。例如, A.__weakref__A.__dict__['__weakref__'] 是一样的.如果这种不一致不存在,使用 A.__dict__行不通,您必须始终使用 vars(A)反而。

    关于python - Python 类的 __dict__.__dict__ 属性是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4877290/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com