Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parametrized inheritance in Python?

I am curious whether there is a better way to achieve something like this? My intentions are to avoid unnecessary boilerplate. The provided example is obviously just simple enough to let the others understand what I had on my mind.

def create_parametrized_class(animal):
    class SomeClass:
        def __init__(self, name):
            self.name = name

        def __str__(self):
            return "{}: {}".format(animal, self.name)

    return SomeClass

class Cat(create_parametrized_class("Cat")):
    pass

class Dog(create_parametrized_class("Dog")):
    pass

cat = Cat("Micka")
dog = Dog("Rex")
assert str(cat) == "Cat: Micka", "Cats..."
assert str(dog) == "Dog: Rex", "Dogs..."
like image 755
Pavel Hanpari Avatar asked Dec 23 '22 15:12

Pavel Hanpari


1 Answers

I'm going to presume that type(self).__name__ won't suffice here (for both your example classes that value is equal to the parameter value you passed in).

To set up per-class values at class-definition time, as of Python 3.6 you can use the __init_subclass__ classmethod:

class Animal:
    def __init_subclass__(cls, animal_name, **kw):
        super().__init_subclass__(**kw)
        self._animal_name = animal_name

    def __str__(self):
        return "{}: {}".format(self._animal_name, self.name)


class Cat(Animal, animal_name='Cat'):
    pass

class Dog(Animal, animal_name='Dog'):
    pass

__init_subclass__ is called for all new subclasses, and any parameters you specify in the class Subclass(...) line are passed into that method, letting you parameterise that specific subclass.

like image 199
Martijn Pieters Avatar answered Jan 08 '23 09:01

Martijn Pieters