Imagine we have a class Animal with a class attribute info, which is a dictionary. There is a class Frog which inherits from Animal and also has a class attribute info. But the attribute info of the Frog class must also include the Animal info.
class Animal:
info = {'one':1, 'two':2}
class Frog(Animal):
info = {'three':3}
assert 'three' in Frog.info
I can use @property
class Frog(Animal):
_info = {'three':3}
@property
def info(self):
return self._info | Frog.info
But this is just fragile. Do the large Python library includes any Class that doesn't overwrite the Class attributes?
If you want the
infovalues to be automatically merged by subclasses, you will need to use a metaclass to achieve this.The metaclass is code which can modify the class definition, so it can look at the value of
infoon the parent class and the value ofinfoin the sub-class as it is being defined ... and it can merge them and set the result of that as the value ofinfoin the resulting sub-class.It would look like this:
You can find more info about Python metaclasses here https://realpython.com/python-metaclasses/#custom-metaclasses
Basically, when Python is reading your class definition, like:
Python takes the details of the new class (the name, base classes and class attrs, which include the methods too) and passes them to the metaclass. At this point the
Animalclass does not exist yet. The metaclass is responsible for creating the new class object (meaning the class itself and not an instance of the class).