Current state
I have an abstract base class that contains data in the form of a numpy array, knows how to work with this data, and which can explain matplotlib how to draw it. To accommodate different types of data, it has a number of subclasses, for example:
class PlotData(): """Base Class""" subclasslist = [] @classmethod def register(cls): super().subclasslist.append(cls) def __new__(self, initdata, *args, **kwargs): for subclass in subclasslist: try: subclass.__test__(initdata) except AssertionError: continue else: break else: raise TypeError("Initdata does not fit any known subclass") return subclass(initdata, *args, **kwargs) class Plot3D(PlotData): """Subclass for 3d-plotting data""" def __test__(initdata): assert Data_is_the_right_kind class Plot_XY(PlotData): """Subclass for for plotting XY relations of data""" def __test__(initdata): assert Data_is_the_right_kind
Problem
now the problem is how to get class references in a subclass. At first I wanted to call super (). Register () in the class body, but im could not get a link to the class itself, which I want to save in the list. A small search yielded two possible solutions, and I was wondering what the best one was.
Solution 1
Adding a call after each class definition, for example:
class Plot_XY(PlotData): """Subclass for for plotting XY relations of data""" def __test__(initdata): assert Data_is_the_right_kind Plot_XY.register()
It works, but it seems a very dirty decision for me - a very important part of the class structure is outside the body.
Decision 2
Another possibility might be class decorators. However, I have never used them before, and the examples I found are usually used to override / add functions to methods. ( here and here , for example). However, I am familiar with function decorators, and the following should be pretty clear on what I'm aiming for (and the dead end version works in the interpreter):
def some_creative_decorator_name(cls): cls.register() return cls
or at least something that works as solution 1 but looks like this:
@some_creative_decorator_name class Plot_XY(PlotData): """Subclass for for plotting XY relations of data""" def __test__(initdata): assert Data_is_the_right_kind
Everything seems to work just as well, but would it be like inheritance? This was one of the problems noted on the linked pages, and I dare not count on it. (I do not expect people to subclass it further, but I really do not want this to be impossible if it were necessary.)
(Of course, other solutions are also welcome.)