0

Is it possible to skip classes in the method resolution order when calling for methods?

For example, super().super()

8
  • 1
    In my own personal opinion, that's WAY less maintainable than just writing GrandParentClass.method( self, a, b, c ). If you really are targeting a specific ancestor, than you have lost the benefit of super anyway. Right? Commented Apr 6, 2021 at 19:28
  • Hmm.. why do you believe that?
    – Malemna
    Commented Apr 6, 2021 at 19:30
  • super is a name in the built-in scope, not an attribute.
    – chepner
    Commented Apr 6, 2021 at 19:33
  • 1
    Readability. The advantage of super is that you don't have to rewrite the code if you change the base class. But when you write super().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. Commented Apr 6, 2021 at 19:33
  • 1
    You can skip one or more classes by providing an appropriate first argument to super, but you need to know which class to use. For example, with an MRO like [A, B, C, D], using super(C).foo() in A.foo will skip B.foo. (That is, skipping requires an absolute starting point, not a relative one.)
    – chepner
    Commented Apr 6, 2021 at 19:35

2 Answers 2

1

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

4
  • "seems not to have the super method" There is no super method at all, that is why you write super() and not self.super().
    – kaya3
    Commented Apr 6, 2021 at 19:43
  • works in python 3.8, which python version are you using? Commented Apr 6, 2021 at 20:02
  • No, 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.
    – kaya3
    Commented Apr 6, 2021 at 20:09
  • 1
    This is the perfect solution, thanks for reading the docs
    – Malemna
    Commented Apr 6, 2021 at 20:29
1

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.

4
  • Adn tbh this code is pretty pointless, because you;ve hardcoded the Parent class in Child...
    – Malemna
    Commented Apr 6, 2021 at 20:49
  • @Malemna You could write 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.
    – kaya3
    Commented Apr 6, 2021 at 20:56
  • although it should mention this is python 2
    – Malemna
    Commented Apr 6, 2021 at 21:22
  • @kaya3 That would break multiple inheritance, why is the reason super exists in the first place.
    – Jasmijn
    Commented Apr 6, 2021 at 23:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.