我的Python模块中有一个类可以使用小部件。它有几种方法可以做到这一点,但我不知道哪些方法(如果有的话)实际上会有效,我可能会想出以后新方法来取消小部件。而且,擦拭小部件可能很昂贵。所以我想让我的类的一个实例能够查看自己,找到它为frobbing小部件提供的所有方法,并开始尝试frob小部件直到它成功,此时它应该停止关心它还没有尝试过的方法。
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
有了这个,我想定义一个类的方法,该方法查找名为^[a-z]+FrobAttempt$
的方法,列出它们,并尝试frob小部件,直到小部件被成功擦除(在它应该停止关心其他方法)或者用尽可能的方法。因为它是我的代码,所以我可以确保whateverFrobAttempt
方法都具有相同的命名约定和必需的参数。如果对方法列表有一些排序,那么最好,以便首先尝试具有更好平均速度的那些,但如果以随机顺序尝试它们是可以接受的。
有没有一种理智的方法来做到这一点,当添加新的weirdFrobAttempt
方法时,它们会被自动尝试,或者我最好只是维护这些方法的硬编码列表并迭代它? / p>
答案 0 :(得分:2)
我喜欢sven关于注册的想法。这很麻烦,但是如果存储方法名称的全局列表是可以的,那么我们可以这样做:
FROB_METHOD_REGISTER = []
def frob_method(fn):
def decorate_frob(fn):
FROB_METHOD_REGISTER.add(fn.__name__)
return fn
return decorate_frob
class WidgetFrobber:
def get_frob_methods(self):
return [getattr(self, method) for method in FROB_METHOD_REGISTER]
@frob_method
def simpleFrobAttempt(widget, data):
# fastest way, might not work
@frob_method
def cleverFrobAttempt(widget, data):
# fiddly, fast, and doesn't always work
@frob_method
def boringFrobAttempt(widget, data):
# works most of the time, often slow
@frob_method
def desperateFrobAttempt(widget, data):
# doesn't always work, pathetically slow
所以你可以做到
for method in my_widget_frobber.get_frob_methods():
#do your thing
不确定这是最好的还是最pythonic的方式,如果某些方法严格优于其他方法,我很想让装饰者使用某种优先级队列/排名架构。
你可以使用__dict__
。例如
[fn for name, fn in WidgetFrobber.__dict__.iteritems() if "FrobAttempt" in name]
会为您提供一系列您正在寻找的方法,但如果有一种方法可以构建更清晰且不具备的代码,我会不建议使用__dict__
之类的内容t访问python内部。几乎总是应该有。