In my Python app, I'm using events to communicate between different plugins. Now, instead of registering the methods to the events manually, I thought I might use decorators to do that for me.
I would like to have it look like this:
@events.listento('event.name')
def myClassMethod(self, event):
...
I have first tried to do it like this:
def listento(to):
def listen_(func):
myEventManager.listen(to, func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return func
return listen_
When I callmyEventManger.listen('event', self.method)
from within the instance, everything is running fine. However, if I use the decorator approach, theself
argument is never passed.
The other approach that I have tried, after searching for a solution on the Internet, is to use a class as a decorator:
class listen(object):
def __init__(self, method):
myEventManager.listen('frontend.route.register', self)
self._method = method
self._name = method.__name__
self._self = None
def __get__(self, instance, owner):
self._self = instance
return self
def __call__(self, *args, **kwargs):
return self._method(self._self, *args, **kwargs)
The problem with this approach is that I don't really understand the concept of__get__
, and that I don't know how I'd incorporate the parameters.
Just for testing I have tried using a fixed event to listen to, but with this approach, nothing happens. When I add print statements, I can see that__init__
is called.
If I add an additional, "old style" event registration, both__get__
and__call__
get executed, and the event works, despite the new decorator.
What would be the best way to achieve what I'm looking for, or am I just missing some important concept with decorators?