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.
精彩评论