Parameterized inheritance in Python?

I am curious if there is a better way to achieve something like this? My intentions are to avoid an unnecessary pattern. The above example is obviously simple enough for others to understand what is 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..."
+4
source share
2 answers

I assume that type(self).__name__here it will not be enough (for both classes of classes this value is equal to the value of the parameter that you passed).

To adjust the values ​​for each class during class definition, with Python 3.6 you can use __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__ , , class Subclass(...), , .

+8

, :

class Animal(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return '{}: {}'.format(type(self).name, self.name)

class Cat(Animal):
    name = 'Cat'

class Dog(Animal):
    name = 'Dog'

(, , ) "" (.. -, , Google, __init_subclasses__).

Python 2, 3:

>>> cat = Cat('Micka')
>>> print(cat)
'Cat: Micka'

classproperty, . , - animal_name:

class Animal(object):

    @classproperty
    def animal_name(cls):
        return cls.__name__

    def __init__(self, name):
        self.name = name

    def __str__(self):
        return '{}: {}'.format(self.animal_name, self.name)


class Cat(Animal):
    pass

class Dog(Animal):
    animal_name = 'Doggo'

:

>>> dog = Dog('Mike')
>>> cat = Cat('Bob')
>>> str(dog)
'Doggo: Mike'
>>> str(cat)
'Cat: Bob'
+1

Source: https://habr.com/ru/post/1682911/


All Articles