An inheritance question: getting the name of the "one up" class

alex23 wuwei23 at
Tue Mar 31 06:29:30 CEST 2009

On Mar 31, 1:13 pm, "Nick" <mediocre_per... at> wrote:
> I want to add a "pedigree" function to Animal so that I can have:
> >>> h = Human()
> >>> h.pedigree()
> human < primate < mammal < animal

class Animal(object):
    def pedigree(cls):
        return [c.__name__ for c in cls.mro() if c is not object]

class Mammal(Animal): pass
class Primate(Mammal): pass
class Human(Primate): pass

>>> h = Human()
>>> h.pedigree()
['Human', 'Primate', 'Mammal', 'Animal']
>>> ' > '.join(h.pedigree())
'Human > Primate > Mammal > Animal'

As long as you're using single inheritance in the way you've outlined
here, you should be able to pull the information out of the class' .mro
() method, which returns the list of classes that an object will
resolve method calls against. If you're using multiple inheritance,
you will need to look into the inspect module or read through the
__bases__ attribute on the class.

> Oh, and while the gurus are at it, what would be the advantage (if any) of
> changing, say
>    Primate.__init__(self)
> to
>    super(Human, self).__init__()

While super() has other advantages, the most immediate for you would
be the ability to change the parent class of an object at the class
definition without having to modify anything in that class's __init__.
For eg, if you decided to add another class - MissingLink - between
Primate & Human, using super() you'd only have to change the class
definiton to read 'class Human(MissingLink):' and super would call the
right initialiser, whereas by using Primate.__init__ within
Human.__init__ you'd have to modify the class in two places.

More information about the Python-list mailing list