If I make a class instance like this
class MyClass(object):
pass
x = MyClass()
I can then set attributes on x as follows:
x.myAttr = 1
or x.__setattr__('myAttr', 1)
However, if I make a dict
d = {}
I cannot set attributes on it. For example, if I do this
d.__setattr__('myAttr', 1)
I get the error " 'dict' object has no attribute 'myAttr' " The same thing happens if I try
d.myAttr = 1
I have noticed that in the case of x.myAttr = 1 what actually happens is that
x.__dict__
gets updated with a new key, so it must be that
d.__setattr__
doesn't work because d doesn't have
d.__dict__
simply because d is a dict. I would appreciate it very much if someone could thoroughly explain what's going on here.
Do all python objects have .__dict__
?
Why does my attempt at calling d.__setattr__
result in an error saying that the attribute doesn't exist?
Is there a specific heirarchy of built-in types that I should know about? A simple reference would be much appreciated.
python 2.6.4
Windows XP Pro x64 SP2
Python setattr() method is used to assign the object attribute its value.
Python setattr() function is used to assign a new value to the attribute of an object/instance. Setattr in python sets a new specified value argument to the specified attribute name of a class/function's defined object.
A dict
instance doesn't have a __dict__
attribute, so you can't assign attributes on it. Most of Python's built-in classes (which are written in C and define attributes differently) don't. If you subclass dict
, the subclass will have a __dict__
attribute and you can then add attributes to instances of the subclass.
copy-paste from docs.python.org:
A special attribute of every module is __dict__. This is the dictionary containing the module’s symbol table. Modifying this dictionary will actually change the module’s symbol table, but direct assignment to the __dict__ attribute is not possible (you can write m.__ dict__['a'] = 1, which defines m.a to be 1, but you can’t write m.__dict__ = {}). Modifying __dict__ directly is not recommended.
http://docs.python.org/library/stdtypes.html
The method
Both lines do the same:
x.__setattr__('a', b)
x.a = b
Like __ add__ is:
x.__add__(b)
x + b
However, you can redefine a dict.__ setattr__ function to whatever you want
edit for 3rd comment:
class x(object):
def __init__(self):
pass
def __setattr__(self, a, b):
print "nope, i will not set the attribute %s = %s" % (a,b)
c = x()
c.a = 4
print c.__dict__
will print "nope, i will not set the attribute a = 4
and c.__dict__
won't have the attribute 'a'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With