【问题标题】:Patterns - Event Dispatcher without else if?模式 - 没有 else if 的事件调度器?
【发布时间】:2011-07-22 20:24:01
【问题描述】:
我正在为 Detours 库创建一个 Python 包装器。该工具的一个部分是调度程序,用于将所有挂钩的 API 调用发送到各种处理程序。
现在我的代码如下所示:
if event == 'CreateWindowExW':
# do something
elif event == 'CreateProcessW':
# do something
elif ...
这感觉很难看。是否有一种模式可以创建事件调度程序,而无需为每个 Windows API 函数创建 elif 分支?
【问题讨论】:
标签:
python
design-patterns
event-handling
【解决方案1】:
我没有在这个区域找到任何优雅的东西,所以我 wrote something 让你做:
from switcheroo import Switch, default
switch = Switch({
'foo': lambda x: x+1,
default: lambda x: x-1,
})
>>> switch['foo'](1)
2
>>> switch['bar'](1)
0
还有一些其他的口味;文档是here,代码在github,包在pypi。
【解决方案2】:
这样做的一个好方法是定义一个类,该类具有与相关 API 函数名称相同的方法,以及一个分派到正确方法的分派方法。例如:
class ApiDispatcher(object):
def handle_CreateWindowExW(self):
# do whatever
def handle_CreateProcessW(self):
# do this one
def dispatch(self, event):
method = getattr(self, 'handle_%s' % event)
method()
【解决方案3】:
通常在这种情况下,如果您有预定义的操作列表,请使用地图,例如
def CreateWindowExW():
print 'CreateWindowExW'
def CreateProcessW():
print 'CreateProcessW'
action_map = {
'CreateWindowExW': CreateWindowExW,
'CreateProcessW': CreateProcessW
}
for action in ['CreateWindowExW', 'UnkownAction']:
try:
action_map[action]()
except KeyError:
print action, "Not Found"
输出:
CreateWindowExW
UnkownAction Not Found
所以使用地图你可以创建一个非常强大的调度器
【解决方案4】:
你可以使用 dispatch dict 方法。
def handle_CreateWindowExW():
print "CreateWindowExW"
#do something
events = {
"CreateWindowExW": handle_CreateWindowExW
}
events[event]()
这样,您可以只添加事件而无需添加不同的if 语句。
【解决方案5】:
那些如果最终将不得不去某个地方。为什么不这样做:
handler = get_handler(event)
handler.process()
在get_handler 中,你有你的ifs,每个返回一个在process 方法中工作的对象。
另一种方法是映射到可调用对象,如下所示:
def react_to_create_window_exw():
# do something with event here
pass
handlers = {
"CreateWindowExW" : react_to_create_window_exw
}
你会这样使用它:
handler = handlers[event]
handler()
这样你就不会使用任何 if/else 条件。