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..."
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With