I have gone through other's excellent explanation. However, I found a simple answer from this blog Python Magic Methods and __getattr__
. All the following are from there.
Using the __getattr__
magic method, we can intercept that inexistent attribute lookup and do something so it doesn’t fail:
class Dummy(object):
def __getattr__(self, attr):
return attr.upper()
d = Dummy()
d.does_not_exist # 'DOES_NOT_EXIST'
d.what_about_this_one # 'WHAT_ABOUT_THIS_ONE'
But if the attribute does exist, __getattr__
won’t be invoked:
class Dummy(object):
def __getattr__(self, attr):
return attr.upper()
d = Dummy()
d.value = "Python"
print(d.value) # "Python"
__getattribute__
is similar to __getattr__
, with the important difference that __getattribute__
will intercept EVERY attribute lookup, doesn’t matter if the attribute exists or not.
class Dummy(object):
def __getattribute__(self, attr):
return 'YOU SEE ME?'
d = Dummy()
d.value = "Python"
print(d.value) # "YOU SEE ME?"
In that example, the d
object already has an attribute value. But when we try to access it, we don’t get the original expected value (“Python”); we’re just getting whatever __getattribute__
returned. It means that we’ve virtually lost the value attribute; it has become “unreachable”.