Here are pastes of draft base classes. These are design level, not work level. They don't relate to the project and would, in a larger project, go in a dependant library. They are small and simple, and I've at other times made forms of them that I prefer over these. They're intended to be refactorable, changing the concepts around for other uses. Notably, in this implementation there is no way yet to add further methods to "Interpretations". I'm still learning effective uses of __new__. This is the first time I've used it. I made a prototype norm of leaving @staticmethod off of the Interpretation method implementations. This is poor style but saves typing. # OpExpr is prototype base class for expressions class OpExpr: def __init__(self, op, *operands): self.op = op self.children = operands def __getitem__(self, idx): return self.children[idx] def __instancecheck__(self, cls): if issubclass(cls, Interpretation): return cls.test(self) else: return super().__instancecheck__(self, cls) def __add__(left, right): return OpExpr(op.add, left, right) def __radd__(right, left): return self.__add__(left) # Interpretation acts like a function associated with a form, that can either create a form of an existing object, or a new object of the form. # I think of it kind of like a proxy without the proxying implemented yet. class Interpretation: def __new__(cls, obj, *params): if len(params) = 0: try: return cls.form(obj) except: return None else: return cls.new(obj, *params) def new(*params): raise NotImplementedError() def form(obj): raise NotImplementedError() @classmethod def test(cls, obj): try: return cls.form(obj) is not None except: return False # Reordered is an interpretation of an expression that changes operand order def _Reordered(*order): class Reordered(Interpretation): def form(expr): return OpExpr(expr.op, [expr[idx] for idx in order]) Reordered.__name__ += '_' + '_'.join(str(idx) for idx in order) return Reordered Reordered10 = _Reordered(1, 0) # Op is an interpretation of an expression that can just be used to check if it has a given operator, without having to type "." and "==" on my phone with my finger issues. def _Op(op): class Op(Interpretation): def new(*operands): return OpExpr(op, *operands) def form(expr): assert expr.op is op return expr Op.__name__ = op.__name__.title() return Op Add = _Op(op.add) Mul = _Op(op.mul)