Is it possible to skip classes in the method resolution order when calling for methods?
For example, super().super()
I read the docs here: https://docs.python.org/3/library/functions.html#super that lead me to this code
class A:
def show(self):
print("A")
class B(A):
def __init__(self):
print("B")
def s(self):
return super()
class C(B):
def __init__(self):
super().s().show()
c = C()
c
See that super returns a proxy object that seems not to have the super method (because i tried and the interpreter told me it doesn't). But you do have the others methods from the class, so this way I could get a proxy from its grandparent to use its methods
super
method at all, that is why you write super()
and not self.super()
.
self.super()
does not work in any version of Python (unless you write a class with your own method named super
). super
is not a method, it is a built-in function like print
or len
. You can't write super().super()
for the same reason you can't write super().print()
to print something out.
super()
in the class definition for FooClass
is shorthand for super(FooClass, self)
. Using this, we can do this:
class Grandparent:
def test(self):
print('grandparent gets called')
class Parent(Grandparent):
def test(self):
super().test()
print('parent gets skipped')
class Child(Parent):
def test(self):
super(Parent, self).test()
print('child gets called')
This "cheats" the MRO by checking the parent's superclass instead of the child's superclass.
super(self.__class__.__bases__[0], self)
instead, if you really want. But I think writing Parent
is clearer, and if you are dependent on using the grandparent class's behaviour rather than the parent class's behaviour then you are already throwing "best practices" out of the window anyway.
super
exists in the first place.
GrandParentClass.method( self, a, b, c )
. If you really are targeting a specific ancestor, than you have lost the benefit ofsuper
anyway. Right?super
is a name in the built-in scope, not an attribute.super
is that you don't have to rewrite the code if you change the base class. But when you writesuper().super()
, someone reading your code is going to have to go digging to find what the grandparent class is. It seems to me that, if you are so tightly tied to your ancestry that you know about something in the grandparent, you might as well just make it explicit. My opinion, your mileage may vary.super
, but you need to know which class to use. For example, with an MRO like[A, B, C, D]
, usingsuper(C).foo()
inA.foo
will skipB.foo
. (That is, skipping requires an absolute starting point, not a relative one.)