模式 - 事件调度程序没有其他如果?

时间:2011-03-25 11:21:24

标签: python design-patterns event-handling

我正在为Detours库创建一个Python包装器。该工具的一部分是调度程序,用于将所有挂钩的API调用发送给各种处理程序。

现在我的代码看起来像这样:

if event == 'CreateWindowExW':
    # do something
elif event == 'CreateProcessW':
    # do something
elif ...

这感觉很难看。是否有创建事件调度程序的模式,而不必为每个Windows API函数创建elif分支?

5 个答案:

答案 0 :(得分:4)

这样做的一个好方法是定义一个类,该类具有等于相关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()

答案 1 :(得分:2)

那些如果最终将不得不去某个地方。为什么不这样做:

handler = get_handler(event)
handler.process()

并在get_handler中有你的ifs,每个都返回一个在process方法中工作的对象。

另一种选择是对callables的映射,如下所示:

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条件。

答案 2 :(得分:2)

您可以使用dispatch dict方法。

def handle_CreateWindowExW():
    print "CreateWindowExW"     
    #do something

events = {
    "CreateWindowExW": handle_CreateWindowExW
}

events[event]()

这样,您只需添加事件而无需添加不同的if语句。

答案 3 :(得分:1)

通常在这种情况下,如果您有预定义的操作列表,请使用地图,例如

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 :(得分:0)

在这个区域,我没有发现任何可以像现在这样优雅的东西,所以我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上。