Patterns - Event Dispatcher without else if?












1















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?










share|improve this question





























    1















    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?










    share|improve this question



























      1












      1








      1








      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?










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 25 '11 at 11:24









      Olli

      1,1821430




      1,1821430










      asked Mar 25 '11 at 11:21









      MikeRandMikeRand

      2,11822851




      2,11822851
























          5 Answers
          5






          active

          oldest

          votes


















          4














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





          share|improve this answer

































            2














            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.






            share|improve this answer































              2














              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.






              share|improve this answer































                1














                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






                share|improve this answer































                  0














                  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.






                  share|improve this answer























                    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
                    });


                    }
                    });














                    draft saved

                    draft discarded


















                    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









                    4














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





                    share|improve this answer






























                      4














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





                      share|improve this answer




























                        4












                        4








                        4







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





                        share|improve this answer















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






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Mar 25 '11 at 12:36









                        jfs

                        262k785531083




                        262k785531083










                        answered Mar 25 '11 at 11:30









                        Daniel RosemanDaniel Roseman

                        445k41576632




                        445k41576632

























                            2














                            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.






                            share|improve this answer




























                              2














                              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.






                              share|improve this answer


























                                2












                                2








                                2







                                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.






                                share|improve this answer













                                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.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Mar 25 '11 at 11:24









                                GeoGeo

                                45.5k90287465




                                45.5k90287465























                                    2














                                    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.






                                    share|improve this answer




























                                      2














                                      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.






                                      share|improve this answer


























                                        2












                                        2








                                        2







                                        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.






                                        share|improve this answer













                                        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.







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Mar 25 '11 at 11:27









                                        IkkeIkke

                                        71.4k2281108




                                        71.4k2281108























                                            1














                                            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






                                            share|improve this answer




























                                              1














                                              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






                                              share|improve this answer


























                                                1












                                                1








                                                1







                                                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






                                                share|improve this answer













                                                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







                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Mar 25 '11 at 11:30









                                                Anurag UniyalAnurag Uniyal

                                                55k28144198




                                                55k28144198























                                                    0














                                                    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.






                                                    share|improve this answer




























                                                      0














                                                      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.






                                                      share|improve this answer


























                                                        0












                                                        0








                                                        0







                                                        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.






                                                        share|improve this answer













                                                        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.







                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered Nov 24 '18 at 0:45









                                                        Chris WithersChris Withers

                                                        1,34521427




                                                        1,34521427






























                                                            draft saved

                                                            draft discarded




















































                                                            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.




                                                            draft saved


                                                            draft discarded














                                                            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





















































                                                            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







                                                            Popular posts from this blog

                                                            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                                                            Calculate evaluation metrics using cross_val_predict sklearn

                                                            Insert data from modal to MySQL (multiple modal on website)