Question

My code is like this, and I want to use super() to inherit the features of Papa, how to do that?

class Mama(object):

    def __init__(self):
        self.name = 'Mama'

    def feature(self):
        print "%s have big eyes" % self.name

class Papa(object):

    def __init__(self):
        self.name = 'Papa'

    def feature(self):
        print "%s have fierce beards" % self.name

class Offspring(Mama,Papa):
    def __init__(self, name):
        self.name = name

    def feature(self):
        super(Offspring, self).feature()

offspring = Offspring('Tommy')

offspring.feature()

# This will result "Tommy have big eyes"
Was it helpful?

Solution

You can alter the MRO (method resolution order) by inheriting from Papa first:

class Offspring(Papa, Mama):

The alternative is to skip the MRO and call the (unbound) method on Papa explicitly:

class Offspring(Mama, Papa):
    def __init__(self, name):
        self.name = name

    def feature(self):
        Papa.feature(self)

OTHER TIPS

All the classes in your heirachy need to use super for it to go through all of the methods. Eventually, you will run into a problem whereby the next superclass is object, which doesn't have feature, so you also need to detect that case and ignore it - ie, you need to do this:

class Mama(object):

    def __init__(self):
        self.name = 'Mama'

    def feature(self):
        try:
            super(Mama, self).feature()
        except AttributeError:
            # only superclass is object
            pass
        print "%s have big eyes" % self.name

class Papa(object):

    def __init__(self):
        self.name = 'Papa'

    def feature(self):
        try:
            super(Papa, self).feature()
        except AttributeError:
            # only superclass is object
            pass
        print "%s have fierce beards" % self.name

class Offspring(Mama,Papa):
    def __init__(self, name):
        self.name = name

    def feature(self):
        super(Offspring, self).feature()

Instead of catching the AttributeError, you could also make a further class that exists only to provide feature (without calling super) for other classes to inherit. Then both Mama and Papa inherit that class and override feature, like this:

 class Grandma(object):
     def feature(self):
         pass

 class Mama(Grandma):
     def feature(self):
        super(Mama, self).feature()
        print "%s have big eyes" % self.name

You may want to consider making feature an abstractmethod, to emphasise that it exists only for inheritance.

In either case, what will happen is that you will keep calling the next method until you get to the end of the chain. If neither Mama nor Papa calls super, you will always stop after one call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top