En Tue, 31 Mar 2009 00:13:44 -0300, Nick <mediocre_per...@hotmail.com> escribió:

I've got a collection of classes describing animals, part of which looks like:

class Animal(object):
    def __init__(self):
        self.pet = False
        self.edible = False
        self.legs = 0
        self.sound = None
        self.name = self.__class__.__name__.lower()

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

(shouldn't be Primate?)

I want to add a "pedigree" function to Animal so that I can have:

h = Human()
h.pedigree()
human < primate < mammal < animal

The subject says `getting the name of the "one up" class` but Python allows for multiple inheritance, so you could have several "one up" classes. Classes have a mro ("method resolution order") that linearizes the inheritance tree in a very specific way. In the case of single inheritance, it returns the sequence of base clases, from last to first (object).

Human.mro() yields:
[<class 'a.Human'>, <class 'a.Primate'>, <class 'a.Mammal'>, <class 'a.Animal'>, <type 'object'>]

We have to omit the last element and take the __name__ of each class. And this is clearly a class method: it doesn't depend on any instance. Let's add this to the Animal class:

    @classmethod
    def pedigree(cls):
        return ' < '.join(base.__name__ for base in cls.mro()[:-1])

Human.pedigree() returns:
Human < Primate < Mammal < Animal

I've been thinking about something like:
def pedigree(self):
    n = self.name
    while n != 'object' # base class of Animal
        print n,
        n = Well, this is where I'm stuck. super(???,???).???
    print

You can't use self.name here -- I assume you want *class* relationships, so you can't use instance data, ok? Each class has a __bases__ attribute, and assuming you only have single inheritance, the "one up" class is __bases__[0] -- you could write pedigree() now using __bases__[0].
(But I'd let Python do the hard work and use mro() instead...)

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__()

None, if you use single inheritance everywhere.

super is very tricky; see:
http://fuhm.net/super-harmful/
and
http://www.artima.com/weblogs/viewpost.jsp?thread=236275

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to