I am not quite familiar with inheritance in Python, what is difference in following code between self.name and self.__dict__[name]? And if test = AttrDict(), why I can use dot to set attribute for test such like test.x = 100?
class AttrDict(dict):
IMMUTABLE = '__immutable__'
def __init__(self, *args, **kwargs):
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__[AttrDict.IMMUTABLE] = False
def __getattr__(self, name):
if name in self.__dict__:
return self.__dict__[name]
elif name in self:
return self[name]
else:
raise AttributeError(name)
def __setattr__(self, name, value):
if not self.__dict__[AttrDict.IMMUTABLE]:
if name in self.__dict__:
self.__dict__[name] = value
else:
self[name] = value
else:
raise AttributeError(
'Attempted to set "{}" to "{}", but AttrDict is immutable'.
format(name, value)
)
"why I can use dot to set attribute for
testsuch liketest.x = 100?"You can always do that, that's how Python attributes works. If you are asking why you can set dict keys using that, that's because of
__setattr__method - it defines how Python handles setting attributes using.. With method signature_setattr__(self, name, value), when you dotest.x = 100you are effectively calling_setattrwith parameterstest, x, 100."what is difference in following code between
self.nameandself.__dict__[name]"I'll just say, such a mix of interfaces is VERY error prone. You've got 3 different ways of setting something that might seems the same thing (
self.name,self.__dict__[name]andself[name]), while in fact there are numerous situations where it's not the case.Below example shows how weirdly this class behaves based on what method you use to set attribute:
As you can see, even most basic behaviour like below is broken with the way this class is written: