让所有属性出现在python的`__dict__`方法中

时间:2016-07-13 22:18:27

标签: python class attributes

请考虑以下python示例:

In [3]: class test(object):
   ...:     attribute='3'
   ...:     def __init__(self):
   ...:         self.other='4'
   ...:         

In [4]: b=test()

In [5]: b.attribute
Out[5]: '3'

In [6]: b.__dict__
Out[6]: {'other': '4'}

为什么__dict__仅显示"other"属性而不显示"atribute"

如何获得包含所有classe属性和值的字典?也就是说,我怎么得到这个?

{'other': '4', 'attribute': '3'}

我的意思是使用__dict__或其他简单的方式。

PS:与this question有关,但无法从那里得到一个字典。

PS2:我不是在寻找test.__dict__b.__class__.__dict__,我正在寻找可以用作

的东西
In [3]: class test(object):
   ...:     attribute='3'
   ...:     def __init__(self):
   ...:         self.other='4'
   ...:     def _print_atr(self):
   ...:         # This should print exactly {'other': '4', 'attribute': '3'}
   ...:         print(self.__all_atr__)

In [4]: b=test()

In [5]: b.attribute
Out[5]: '3'

In [6]: b.__dict__
Out[6]: {'other': '4'}

干杯

3 个答案:

答案 0 :(得分:4)

attribute不是实例属性,而是类属性(可以在 mappingproxy test.__dict__中看到)。

如果您从实例更新attribute的值,则可以在实例__dict__中获取attribute

>>> b = test()
>>> b.__dict__
{'other': '4'}
>>> b.attribute
'3'
>>> b.attribute = 5
>>> b.__dict__
{'attribute': 5, 'other': '4'}

或者用

保留原始值
>>> b.attribute  = b.__class__.attribute # may not be necessary

或者您可以更改类的定义并将attribute移动到其中一个类方法中,并通过self将其绑定到实例。

答案 1 :(得分:2)

b.__dict__只是b上的属性映射,而不是b类的属性映射(注意__init__也不存在) 。 b类上的属性位于班级__dict__上。

>>> class test(object):
...   attribute = 1
...   def __init__(self):
...     self.other = 2
... 
>>> b = test()
>>> b.__dict__
{'other': 2}
>>> test.__dict__
dict_proxy({'__module__': '__main__', 'attribute': 1, '__dict__': <attribute '__dict__' of 'test' objects>, '__weakref__': <attribute '__weakref__' of 'test' objects>, '__doc__': None, '__init__': <function __init__ at 0x1030f72a8>})

如果你想要两者,你可以这样做:

d = dict(vars(type(b)))
d.update(vars(b))

(请注意,有些人更喜欢vars(b)b.__dict__)当然,这不会得到子类...

如果你想要子类,你需要走方法解析顺序......

d = {}
for cls in type(b).__mro__:
    d.update(vars(cls))
d.update(vars(b))

答案 2 :(得分:0)

尝试输入:

test.__dict__

它会显示带有&#39;属性的键。这恰好是因为属性是类变量而不是实例变量。