Blowsh1t
Blowsh1t

Reputation: 127

dynamic inheritance function

I am new do python OOP.

I have a problem that I can't solve by myself and even after hours of consulting the internet I am not a single step closer to an solution.

I have a linear class hierarchy where classes inherit parent classes.

For example:

class Animal:
    food = "everything"

class Carnivore(Animal) :
    food = "flesh"

class Wolf(Carnivore) :
    food = "big animals"

class Dog(Wolf) :
    food = "dog food"

Pretty simple. Each class is inheriting from another class and has the same attribute, which gets overwritten each time.

Now I want a single function, to get all the values of food.

This function should be recursive. I am thinking of something like this :

def get_food(self) :
        print(self.food)
        super().get_food()

Which then can be called like:

Dog.get_food()

The problem is, that the instance using the function never changes. This means I will always get "dog food" as an answer.

Is there any way to iterate throuhg all parent classes with a single function and get their attribute?

I dont want the same function written in all classes with a statement like:

print(Wolf.food)

For a easier maintenance.

Many thanks for any help or advice.

Edit:

The expected outcome for the call:

Dog.get_food()

would be :

dog food
big animals
flesh
everything

Upvotes: 2

Views: 82

Answers (1)

Marko Borković
Marko Borković

Reputation: 1912

Hopefully I understood what you want to do correctly.

The only way I know how to do this is really tricky and you have to dive into the guts of python. You have to utilize the Method Resolution Order.

But be careful MRO can get really tricky in more complex examples and I don't suggest doing this in production code, EVER. But all that said it is a cool a thing to learn.

Essentially what this code does is it loops through the all the classes you inherit from and prints out the food property of that class.

class Animal:
    food = "everything"
    def get_food(self):
        for _class in self.__class__.__mro__[:-1]:
            print(_class.food)
...

class Dog(Wolf):
    food = "dog food"

d = Dog()
d.get_food()

Note that we don't loop through the last class in the MRO because that is the generic object class and it doesn't have the food property.

Output:

dog food
big animals
flesh
everything

Upvotes: 2

Related Questions