I have a class hierarchy where some methods work with a list of properties defined at the class level.
Let's say that for class A
I have A.X = [propA1, propA2]
and for subclass C
I need C.X = [propA1, propA2, propC]
. Subclasses inherit the properties from the parents, so it would make sense to write class methods with super()
calls, each one using the properties of their own class.
However, it is a bit cumbersome. I can deal with all properties in a single method in the base class. So it really feels more natural to define a class variable containing an array of new properties for each subclass and manually go down the cls.__mro__
to retrieve all properties.
What I've come up with (below) seems to work relatively transparently but is it idiomatic? Is there a more typical coding pattern for this? Is there a way to avoid decorating all subclasses?
class Base(object):
pass
class InheritClassVariable:
def __init__(self, var, base):
self.var = var
self.base = base
def __call__(self, cls):
name = self.var
uname = '_' + name
bases = [B for B in cls.__mro__ if issubclass(B, self.base)]
setattr(cls, uname, getattr(cls, name, []))
value = [item for B in bases for item in getattr(B, uname, [])]
setattr(cls, name, value)
return cls
@InheritClassVariable('X', Base)
class A(Base):
X = ['propA1', 'propA2']
@InheritClassVariable('X', Base)
class B(Base):
X = ['propB']
@InheritClassVariable('X', Base)
class C(A):
X = ['propC']
@InheritClassVariable('X', Base)
class D(C,B,A):
X = ['propD']
if __name__ == "__main__":
print(f"D.X = {D.X}")