繁体   English   中英

__dict__ Python 中终极基础 Class、object 的属性

[英]__dict__ Attribute of Ultimate Base Class, object in Python

以下代码按排序顺序列出了名为“A”的 class 的属性:-

>>> class A():
        def __init__(self, i):
            self.at = i

>>> sorted(vars(A))
['__dict__', '__doc__', '__init__', '__module__', '__weakref__']

现在,打印键的值, '__dict__'结果是:-

>>> vars(A)['__dict__']                 #Value of '__dict__'
<attribute '__dict__' of 'A' objects>

根据文档, vars([object])

返回模块、class、实例或任何其他具有__dict__属性的 object 的__dict__属性。


我不明白的是列表中的'__dict__'属性与vars()用来返回A的属性的属性相同,或者它是具有其他目标的不同属性,例如按照建议实现 A 的对象的命名空间(据我说)'__dict__'持有的价值。


编辑:-

问题的第一部分与另一个问题(也由@eliotness 提到)非常相关,但它是第二部分(如下所述),我找不到任何答案或相关问题,因此,更改标题问题。


让我们考虑另一个代码,它在 Python、 object中生成最终基础 class 的属性列表:-

>>> sorted(vars(object))
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', ...., '__str__', '__subclasshook__']
>>> hasattr(object, '__dict__')
True
>>> sorted(getattr(object, '__dict__')) == sorted(vars(object))
True

另一个关于object.__dict__的文档引用

字典或其他映射 object 用于存储对象的(可写)属性。


这一次, '__dict__'没有出现在object的列表中。 那么,在__dict__或任何其他原因的情况下, object属性是只读属性吗?

另外,是否有可能以任何方式获取 Python 中的只读属性列表


首先我想说我只知道部分你的问题的答案。 关于 python 的行为,第二部分可能并不完全正确。 但首先,我想澄清一些事情:您引用的文档涉及普通对象,可能不适用于元类,因为它们的内部行为完全编码在 C 中。

vars(A)['字典']

据我了解 python 的工作原理,我怀疑您在此处看到的__dict__

>>> vars(A)['__dict__']                 #Value of '__dict__'
<attribute '__dict__' of 'A' objects>

我怀疑它是 class 未来实例的__dict__属性的样本。 我现在没有更好的答案,但让我们继续挖掘。

元类的__dict__属性

由于object是 class type ,因此没有__dict__是很正常的,因为无法在 int、float 或 str 等基本类型上添加属性。 那么,如果不使用这些类型,为什么会有__dict__属性?

最后,是的。 类和元类的__dict__属性有限制。 这些限制采用 class MappingProxy 的形式,如vars文档中所述:

模块和实例等对象具有可更新的__dict__属性; 但是,其他对象可能对其__dict__属性有写入限制(例如,类使用 types.MappingProxyType 来防止直接字典更新)。

但是这种行为也在class object 的文档中明确说明

编辑:我开始找到关于奇怪的vars(A)['__dict__']好信息。 看看这里

链接的答案已经回答了您问题的第一部分:实例的__dict__存储为 class 上的描述符 这是A.__dict__['__dict__'] 另一方面, A.__dict__存储A class 的所有属性 - 它本身就是type的实例。 所以实际上是type.__dict__['__dict__']提供了这些变量:

>>> type.__dict__['__dict__']
<attribute '__dict__' of 'type' objects>
>>> A.__dict__ == type.__dict__['__dict__'].__get__(A)
True

您在object上没有看到__dict__属性的原因是它没有。 这意味着您不能在object实例上设置实例变量:

>>> o = object()
>>> o.x = 1

AttributeError: 'object' object has no attribute 'x'

通过定义__slots__可以为自定义类实现类似的行为:

>>> class B:
...     __slots__ = ()
... 
>>> vars(B)
mappingproxy({'__module__': '__main__', '__slots__': (), '__doc__': None})
>>> 
>>> b = B()
>>> b.x = 1

AttributeError: 'B' object has no attribute 'x'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM