[英]__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 中。
据我了解 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.