First of all, the __getattribute__
is a magic method (aka dunder
method/double underscore method). This is a property/attribute accessor method and it intercepts on every property/attribute access even if the property/attribute is available in the class itself. On the other hand, the __getattr__
magic method is called only if the property you are accessing doesn't exist in the class/instance. Anyways...
There is also one more important thing to notice that, as you might already know that, all classes extends/inherits the base object
class implicitly or explicitly. So, any class you define, the default parent class is the built-in object
class. You are confused as you asked:
I understand (hopefully) that super().__getattribute__(value)
reaches
out to the object
class in this case. But how actually does object
fetch the name
value out of the test()
class?
So lets see some basic examples first:
class Foo:
def __init__(self, name):
self.name = name
def __getattribute__(self, name):
return super().__getattribute__(name)
is equivalent to
class Foo(object):
def __init__(self, name):
self.name = name
def __getattribute__(self, name):
return object.__getattribute__(self, name)
So, when you call
object.__getattribute__(self, name)
You are passing the context (an instance of the class) explicitly to the parent (object
) class. so the parent/object class knows the context and get the attribute from that passed instance. On the other hand, when you call:
super().__getattribute__(name)
Python sets the context for you. So, you can imagine something like this:
super(test, self).__getattribute__(name) # it's valid
But in this case, it's implicit, that's how the super()
call knows where to lookup for the attribute. It's worth mentioning that, Python's super()
builtin function returns a proxy object, a substitute object that can call the method of the base class via delegation and also super()
can take two parameters (as you've seen in previous code snippet), the first is the subclass type (in this case test
), and the second parameter is an object, an instance of that subclass (test
).
In Python 3
, the super(test, self)
call is equivalent to the parameterless super()
call. Hope I've clarified your confusions. You may read more about super().