2011-03-25 2 views
0

나는 Detours 라이브러리를위한 파이썬 래퍼를 만들고있다. 이 도구의 한 부분은 모든 후크 API 호출을 다양한 핸들러로 보내는 디스패처입니다.패턴 - 예외가없는 이벤트 발송자는?

는 지금 내 코드는 다음과 같습니다 :이 추한 느낌

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

. 각 Windows API 함수에 대해 elif 분기를 만들지 않고도 이벤트 디스패처를 만들 수있는 패턴이 있습니까?

답변

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() 
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() 

어떤/경우 다른 조건을 사용하지 것이다이 방법을.

2

발송 방법을 사용할 수 있습니다.

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

events = { 
    "CreateWindowExW": handle_CreateWindowExW 
} 

events[event]() 

이 방법, 당신은 단지 다른 if 문을 추가하지 않고도 이벤트를 추가 할 수 있습니다.

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 

은 그래서 당신은 매우 강력한 디스패처를 만들 수 있습니다지도를 사용하여