I have number of subclasses all of which have number of methods whose names start with "on.." eg.:
def on_index(self):
raise NotImplementedError()
def on_spiking_intent(self):
raise NotImplementedError()
def on_no_option(self):
raise NotImplementedError()
I would like to write a method in the superclass which prints a list of all the "on..." methods of its subclasses and specifies to which subclass the method belongs.
I guess this get_all_on_methods method need not be in the superclass, but it made sense to me to put it there as only the superclass unites the subclasses.
How should I go about this? I was thinking about somehow using decorators like putting
@onmethod
in front of every "on..." method or also somehow using an abstract class. But I actually don't know.
You can iterate over the subclasses of some class using the __subclasses__()
method. You can check the namespace of the subclasses for attributes that start with "on_"
, so something to the effect of:
class Ur:
@classmethod
def get_all_on_methods(cls):
results = []
for klass in cls.__subclasses__():
for name, attribute in vars(klass).items():
if name.startswith("on_"):
results.append((attribute, klass))
return results
class Foo(Ur):
def on_index(self):
pass
def some_method(self):
pass
class Bar(Ur):
def on_spiking_intent(self):
pass
def another_method(self):
pass
This populates a list for illustration purposes, you could easily populate a dictionary or whatever you want instead.
Also, this gets any class attribute, so you might want to check if it is a method by using:
if callable(attribute) and name.startswith("on_"):
...
But that is up to you.
Here's the output you get in the above example:
In [2]: Ur.get_on_methods()
Out[2]:
[(<function __main__.Foo.on_index(self)>, __main__.Foo),
(<function __main__.Bar.on_spiking_intent(self)>, __main__.Bar)]