nKandel nKandel - 3 months ago 12
Python Question

Call Grandparent Method without executing parent method through Mixin

I need to override Parent method and call Grandparent method through mixin. Is it possible?

For example:

A
and
B
are library classes.

class A(object):
def class_name(self):
print "A"


class B(A):
def class_name(self):
print "B"
super(B, self).class_name()
# other methods ...


Now I need to override
class_name
method from
B
and call it's super.

class Mixin(object):
def class_name(self):
print "Mixin"
# need to call Grandparent class_name instead of parent's
# super(Mixin, self).class_name()


class D(Mixin, B):
# Here I need to override class_name method from B and call B's super i.e. A's class_name,
# It is better if I can able to do this thourgh Mixin class. (
pass


Now when I called
D().class_name()
, it should print
"Mixin" and "A"
only. Not "B"

Answer

One method is to use inspect.getmro() but that is likely to break if the user writes class D(B, Mixin).

Let me demonstrate:

class A(object):
    def class_name(self):
        print "A"


class B(A):
    def class_name(self):
        print "B"
        super(B, self).class_name()
    # other methods ...

class Mixin(object):
    def class_name(self):
        print "Mixin"
        # need to call Grandparent class_name instead of parent's
        # super(Mixin, self).class_name()


class D(Mixin, B):
    # Here I need to override class_name method from B and call B's super i.e. A's class_name, 
    # It is better if I can able to do this thourgh Mixin class. (
    pass

class E(B, Mixin): pass


import inspect
print inspect.getmro(D) # returns tuple with (D, Mixin, B, A, object)
print inspect.getmro(E) # returns tuple with (E, B, A, Mixin, object)

So if you have control and can ensure that you always get Mixin first. You can use getmro() to get the grandparent and execute it's class_name function.