Reputation: 3507
Please consider the following python example:
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'}
Why is it that __dict__
only shows the "other"
attribute and not "atribute"
?
And how do I get a dictionary with all the classe's attributes and values? That is, how do I get this?
{'other': '4', 'attribute': '3'}
And I mean by using __dict__
or by some other simple means.
PS: related to this question, but couldn't quite get a dict from there.
PS2: I'm not look for test.__dict__
or b.__class__.__dict__
, I'm looking for something that can be used as
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'}
Cheers
Upvotes: 7
Views: 6302
Reputation: 309821
b.__dict__
is only a mapping of attributes on b
, not on b
's class (notice that __init__
isn't there either). The attributes on b
's class are on the class's __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>})
If you want both, you can do something like:
d = dict(vars(type(b)))
d.update(vars(b))
(note that some prefer vars(b)
to b.__dict__
) Of course, this doesn't get subclasses ...
If you want subclasses, you'll need to walk the method resolution order...
d = {}
for cls in type(b).__mro__:
d.update(vars(cls))
d.update(vars(b))
Upvotes: 3
Reputation: 78536
attribute
is not an instance attribute but a class attribute (can be seen in the mappingproxy test.__dict__
).
You can get attribute
in the instance __dict__
if you update the value of attribute
from the instance:
>>> b = test()
>>> b.__dict__
{'other': '4'}
>>> b.attribute
'3'
>>> b.attribute = 5
>>> b.__dict__
{'attribute': 5, 'other': '4'}
Or keep the original value with
>>> b.attribute = b.__class__.attribute # may not be necessary
Or you could change the definition of the class and move attribute
into one of the class methods and bind it to the instance via self
.
Upvotes: 8
Reputation: 81
Try typing:
test.__dict__
And it shows a key with 'attribute'. This happens exactly because attribute is a class variable not an instance variable.
Upvotes: 1