I have a series of classes all, inheriting from one of several possible parents which all share a base class. Each class has a class-scope Dict[str, object] parameters
which is based on the base class parameters
from copy import deepcopy
class BaseClass:
parameters = {
'example_param1': ParamObject(name='example_param1', editable=True),
}
class MiddleClass(Baseclass):
parameters = {
**deepcopy(Baseclass.parameters),
'example_param2': ParamObject(name='example_param2', editable=False),
}
class ChildClass(MiddleClass):
parameters = {
**deepcopy(MiddleClass.parameters),
'example_param3': ParamObject(name='example_param3', editable=True),
}
This implementation does the job, but I find the **deepcopy(Baseclass.parameters),
line unsatisfying. These child classes are going to be edited over time by someone with only a basic understanding of coding so I want to make the code as simple and cut-and-pasteable as possible.
Is there anything I can call at class scope to get the equivilant of super().__class__
? I want the user to be able to change the base class from, say, MiddleClass
to MiddleClass2
without needing to remember to change the base class in multiple locations.
You could do this with a metaclass. Check all of the classes in the inheritance tree to see if they have the parameter
s field. If they do, then merge them together and set the property on the class instance.
class ParamMeta(type):
def __init__(cls, name, bases, dct):
class_types = [cls] + list(bases)
parameters = {}
for class_type in class_types:
if hasattr(class_type, "parameters"):
parameters.update(class_type.parameters)
cls.parameters = parameters
super().__init__(name, bases, dct)
Example:
class Foo(metaclass=ParamMeta):
parameters = {"a": "b"}
class Bar(Foo):
pass
class Fizz(Bar):
parameters = {"c": "d"}
print(Foo.parameters)
print(Bar.parameters)
print(Fizz.parameters)
Outputs:
{'a': 'b'}
{'a': 'b'}
{'c': 'd', 'a': 'b'}