I have a class in my Python module that frobs widgets. It has several ways to do this, but I don’t know ahead of time which ones, if any, will actually work, and I might figure out new ways to frob the widgets later. Also, frobbing widgets can be expensive. So I’d like to have an instance of my class be able to look at itself, find all of the methods that it has for frobbing widgets, and to start trying to frob widgets until it succeeds, at which point it should stop caring about the methods it hasn’t yet tried.
class WidgetFrobber:
def simpleFrobAttempt(widget, data):
# fastest way, might not work
def cleverFrobAttempt(widget, data):
# fiddly, fast, and doesn't always work
def boringFrobAttempt(widget, data):
# works most of the time, often slow
def desperateFrobAttempt(widget, data):
# doesn't always work, pathetically slow
With that in place, I’d like to define a method of the class that looks for methods named ^[a-z]+FrobAttempt$, makes a list of them, and tries to frob widgets until the widget is successfully frobbed (at which point it should stop caring about other methods) or it runs out of possible methods. Since it’s my code, I can make sure that the whateverFrobAttempt methods all have the same naming conventions and required arguments. It’s best if there’s some ordering to the list of methods, so that the ones with a better average speed get tried first, but it’s acceptable if they’re attempted in random-ish order.
Is there a sane way to do this such that when new weirdFrobAttempt methods are added, they’ll be tried automatically, or am I better off just maintaining a hardcoded list of such methods and iterating over that ?
I like sven’s idea of having a register. This is hacky, but if storing a global list of method names is ok then we could do something like this:
so then you can do
Not sure if this is the best or most pythonic way, and I’d be tempted to make the decorator use some sort of priority queue/ranking schema if there are some methods that are strictly better than others.
You could use
__dict__. for examplewould give you the set of methods you are looking for, but I would not recommend using things like
__dict__if there is a way to build code that is more clear and doesn’t access python internals. And there almost always should be.