开发者

Registering per-class handlers

开发者 https://www.devze.com 2023-03-14 02:22 出处:网络
I\'m trying to find a good way to easily register handlers of some commands in a Python class. Those handlers would be registered for subclasses of SomeBaseClass and only available there. Unfortunatel

I'm trying to find a good way to easily register handlers of some commands in a Python class. Those handlers would be registered for subclasses of SomeBaseClass and only available there. Unfortunately I'm starting to think I'm doing way more work than necessary. Right now, I've got:

def register_handlers(cls):
    cls._handlers = {}
    for method in cls.__dict__.values():
        if hasattr(method, "handler_name"):
            cls._handlers[method.handler_name] = method
    return cls

class SomeBaseClass(object):
    _handlers = None
    def __init__(self):
        for h in self._handlers:
            self._handlers[h] = types.MethodType(self._handlers[h], self, SomeBaseClass)
    def run_action(self, name, *args):
        return self._handlers[name](*args)

def actual_handler_wrapper(f):
    ....
    f.handler_name = name
    ....

There are a couple of issues here:

  • both the class and it's handlers have to be decorated
  • second level of subclasses is not easily available (_handlers would have to be assigned and checked on every level of inheritance)
  • binding handlers to a class during initialisation seems dirty...

Is there some way to improve this? I could probably get rid of register_handlers by changing SomeBaseClass to be a meta-clas开发者_C百科s. It could also bind handlers at class creation time. But that seems even more complicated than the current approach.

Is there some easier way out?

Edit: Sample usage:

@register_handlers
class SubClass(SomeBaseClass):
    @actual_handler_wrapper
    def handler(self):
       ...


You're overthinking the problem. If you have one handler per action, then just make up a naming convention for them, like this:

class SomeBaseClass(object):
    def run_action(self, name, *args):
        getattr(self, name + '_handler')(*args)

class SubClass(SomeBaseClass):
    def foo_handler(self):
        # called on run_action('foo')

Then again, you might just drop the run_action method altogether, but I guess that depends on how it's going to be called, and on your personal preferences.

0

精彩评论

暂无评论...
验证码 换一张
取 消