Patterns - Event Dispatcher without else if?
I'm creating a Python wrapper for the Detours library. One piece of the tool is a dispatcher to send all of the hooked API calls to various handlers.
Right now my code looks like this:
if event == 'CreateWindowExW':
# do something
elif event == 'CreateProcessW':
# do something
elif ...
This feels ugly. Is there a pattern to create an event dispatcher without my having to create an elif
branch for each Windows API function?
python design-patterns event-handling
add a comment |
I'm creating a Python wrapper for the Detours library. One piece of the tool is a dispatcher to send all of the hooked API calls to various handlers.
Right now my code looks like this:
if event == 'CreateWindowExW':
# do something
elif event == 'CreateProcessW':
# do something
elif ...
This feels ugly. Is there a pattern to create an event dispatcher without my having to create an elif
branch for each Windows API function?
python design-patterns event-handling
add a comment |
I'm creating a Python wrapper for the Detours library. One piece of the tool is a dispatcher to send all of the hooked API calls to various handlers.
Right now my code looks like this:
if event == 'CreateWindowExW':
# do something
elif event == 'CreateProcessW':
# do something
elif ...
This feels ugly. Is there a pattern to create an event dispatcher without my having to create an elif
branch for each Windows API function?
python design-patterns event-handling
I'm creating a Python wrapper for the Detours library. One piece of the tool is a dispatcher to send all of the hooked API calls to various handlers.
Right now my code looks like this:
if event == 'CreateWindowExW':
# do something
elif event == 'CreateProcessW':
# do something
elif ...
This feels ugly. Is there a pattern to create an event dispatcher without my having to create an elif
branch for each Windows API function?
python design-patterns event-handling
python design-patterns event-handling
edited Mar 25 '11 at 11:24
Olli
1,1821430
1,1821430
asked Mar 25 '11 at 11:21
MikeRandMikeRand
2,11822851
2,11822851
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
One nice way to do this is to define a class which has methods equating to the relevant API function names, plus a dispatch method which dispatches to the correct method. For example:
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()
add a comment |
Those if's will eventually have to go somewhere. Why not do it like this:
handler = get_handler(event)
handler.process()
and in the get_handler
you'd have your ifs, each returning an object which does its work in the process
method.
An alternative would be a map to callables, like this:
def react_to_create_window_exw():
# do something with event here
pass
handlers = {
"CreateWindowExW" : react_to_create_window_exw
}
and you would use it like this:
handler = handlers[event]
handler()
This way you would not use any if/else conditions.
add a comment |
You can use the dispatch dict method.
def handle_CreateWindowExW():
print "CreateWindowExW"
#do something
events = {
"CreateWindowExW": handle_CreateWindowExW
}
events[event]()
This way, you can just add events without having to add different if
statements.
add a comment |
Usually in such cases when you have a predefined list of actions to take, use a map e.g.
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"
Output:
CreateWindowExW
UnkownAction Not Found
so using a map you can create a very powerful dispatcher
add a comment |
I didn't find anything that was as graceful as it could be in this area, so I wrote something that let's you do:
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
There are some other flavours; docs are here, code is on github, package is on pypi.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5431732%2fpatterns-event-dispatcher-without-else-if%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
One nice way to do this is to define a class which has methods equating to the relevant API function names, plus a dispatch method which dispatches to the correct method. For example:
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()
add a comment |
One nice way to do this is to define a class which has methods equating to the relevant API function names, plus a dispatch method which dispatches to the correct method. For example:
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()
add a comment |
One nice way to do this is to define a class which has methods equating to the relevant API function names, plus a dispatch method which dispatches to the correct method. For example:
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()
One nice way to do this is to define a class which has methods equating to the relevant API function names, plus a dispatch method which dispatches to the correct method. For example:
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()
edited Mar 25 '11 at 12:36
jfs
262k785531083
262k785531083
answered Mar 25 '11 at 11:30
Daniel RosemanDaniel Roseman
445k41576632
445k41576632
add a comment |
add a comment |
Those if's will eventually have to go somewhere. Why not do it like this:
handler = get_handler(event)
handler.process()
and in the get_handler
you'd have your ifs, each returning an object which does its work in the process
method.
An alternative would be a map to callables, like this:
def react_to_create_window_exw():
# do something with event here
pass
handlers = {
"CreateWindowExW" : react_to_create_window_exw
}
and you would use it like this:
handler = handlers[event]
handler()
This way you would not use any if/else conditions.
add a comment |
Those if's will eventually have to go somewhere. Why not do it like this:
handler = get_handler(event)
handler.process()
and in the get_handler
you'd have your ifs, each returning an object which does its work in the process
method.
An alternative would be a map to callables, like this:
def react_to_create_window_exw():
# do something with event here
pass
handlers = {
"CreateWindowExW" : react_to_create_window_exw
}
and you would use it like this:
handler = handlers[event]
handler()
This way you would not use any if/else conditions.
add a comment |
Those if's will eventually have to go somewhere. Why not do it like this:
handler = get_handler(event)
handler.process()
and in the get_handler
you'd have your ifs, each returning an object which does its work in the process
method.
An alternative would be a map to callables, like this:
def react_to_create_window_exw():
# do something with event here
pass
handlers = {
"CreateWindowExW" : react_to_create_window_exw
}
and you would use it like this:
handler = handlers[event]
handler()
This way you would not use any if/else conditions.
Those if's will eventually have to go somewhere. Why not do it like this:
handler = get_handler(event)
handler.process()
and in the get_handler
you'd have your ifs, each returning an object which does its work in the process
method.
An alternative would be a map to callables, like this:
def react_to_create_window_exw():
# do something with event here
pass
handlers = {
"CreateWindowExW" : react_to_create_window_exw
}
and you would use it like this:
handler = handlers[event]
handler()
This way you would not use any if/else conditions.
answered Mar 25 '11 at 11:24
GeoGeo
45.5k90287465
45.5k90287465
add a comment |
add a comment |
You can use the dispatch dict method.
def handle_CreateWindowExW():
print "CreateWindowExW"
#do something
events = {
"CreateWindowExW": handle_CreateWindowExW
}
events[event]()
This way, you can just add events without having to add different if
statements.
add a comment |
You can use the dispatch dict method.
def handle_CreateWindowExW():
print "CreateWindowExW"
#do something
events = {
"CreateWindowExW": handle_CreateWindowExW
}
events[event]()
This way, you can just add events without having to add different if
statements.
add a comment |
You can use the dispatch dict method.
def handle_CreateWindowExW():
print "CreateWindowExW"
#do something
events = {
"CreateWindowExW": handle_CreateWindowExW
}
events[event]()
This way, you can just add events without having to add different if
statements.
You can use the dispatch dict method.
def handle_CreateWindowExW():
print "CreateWindowExW"
#do something
events = {
"CreateWindowExW": handle_CreateWindowExW
}
events[event]()
This way, you can just add events without having to add different if
statements.
answered Mar 25 '11 at 11:27
IkkeIkke
71.4k2281108
71.4k2281108
add a comment |
add a comment |
Usually in such cases when you have a predefined list of actions to take, use a map e.g.
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"
Output:
CreateWindowExW
UnkownAction Not Found
so using a map you can create a very powerful dispatcher
add a comment |
Usually in such cases when you have a predefined list of actions to take, use a map e.g.
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"
Output:
CreateWindowExW
UnkownAction Not Found
so using a map you can create a very powerful dispatcher
add a comment |
Usually in such cases when you have a predefined list of actions to take, use a map e.g.
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"
Output:
CreateWindowExW
UnkownAction Not Found
so using a map you can create a very powerful dispatcher
Usually in such cases when you have a predefined list of actions to take, use a map e.g.
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"
Output:
CreateWindowExW
UnkownAction Not Found
so using a map you can create a very powerful dispatcher
answered Mar 25 '11 at 11:30
Anurag UniyalAnurag Uniyal
55k28144198
55k28144198
add a comment |
add a comment |
I didn't find anything that was as graceful as it could be in this area, so I wrote something that let's you do:
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
There are some other flavours; docs are here, code is on github, package is on pypi.
add a comment |
I didn't find anything that was as graceful as it could be in this area, so I wrote something that let's you do:
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
There are some other flavours; docs are here, code is on github, package is on pypi.
add a comment |
I didn't find anything that was as graceful as it could be in this area, so I wrote something that let's you do:
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
There are some other flavours; docs are here, code is on github, package is on pypi.
I didn't find anything that was as graceful as it could be in this area, so I wrote something that let's you do:
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
There are some other flavours; docs are here, code is on github, package is on pypi.
answered Nov 24 '18 at 0:45
Chris WithersChris Withers
1,34521427
1,34521427
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5431732%2fpatterns-event-dispatcher-without-else-if%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown