I thought super() would always try to run with method(or attribute) in base class until I encountered a use case that gets attribute of child class with super().__getattribute__("foo"). Simplified code shows as below.
class Base:
value = "base"
def foo(self):
print(f"Base foo, {self.value}")
class Derived(Base):
value = "derived"
def foo(self):
print(f"Derived foo, {self.value}")
def bar(self):
print(f"Derived bar {self.value}")
print(super().value)
print(super().__getattribute__("value"))
super().foo()
super().__getattribute__('foo')()
d = Derived()
d.bar()
the output,
Derived bar derived
base
derived
Base foo, derived
Derived foo, derived
is somewhat beyond my previous understanding, is only __getattribute__ an exception? I can not get any further detail with this doc, hope anyone can help me understand this clearer, thanks!
Edit to follow __getattribute__ issue, as below:
class Base:
value = "base"
def foo(self):
print(f"Base foo, {self.value}")
def __getattribute__(self, k):
print(f"Base get attr {self}, {k}")
return super().__getattribute__(k)
class Derived(Base):
value = "derived"
def foo(self):
print(f"Derived foo, {self.value}")
def __getattribute__(self, k):
print(f"Derived get attr {self}, {k}")
return super().__getattribute__(k)
def bar(self):
print("Derived bar")
print(super().value)
print(super().__getattribute__("value"))
d = Derived()
d.bar()
and output is:
Derived get attr <__main__.Derived object at 0x7fb0621dba90>, bar
Base get attr <__main__.Derived object at 0x7fb0621dba90>, bar
Derived bar
base
Base get attr <__main__.Derived object at 0x7fb0621dba90>, value
derived