【发布时间】:2011-03-25 00:07:35
【问题描述】:
在我的 Python 应用程序中,我使用事件在不同插件之间进行通信。 现在,与其手动将方法注册到事件中,我想我可以使用装饰器来为我做这件事。
我想让它看起来像这样:
@events.listento('event.name')
def myClassMethod(self, event):
...
我第一次尝试这样做:
def listento(to):
def listen_(func):
myEventManager.listen(to, func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return func
return listen_
当我在实例中调用myEventManger.listen('event', self.method)时,一切都运行良好。但是,如果我使用装饰器方法,selfargument 永远不会通过。
我在网上搜索解决方案后尝试的另一种方法是使用类作为装饰器:
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)
这种方法的问题是我不太了解__get__ 的概念,也不知道如何合并参数。
只是为了测试,我尝试使用固定事件来收听,但是使用这种方法,什么也没有发生。当我添加打印语句时,我可以看到 __init__ 被调用。
如果我添加一个额外的“旧式”事件注册,__get__和__call__get 都被执行,尽管有新的装饰器,该事件仍然有效。
什么是实现我正在寻找的最佳方式,或者我只是错过了装饰器的一些重要概念?
【问题讨论】:
-
您确定在定义方法后只调用
myEventManager.listen('frontend.route.register', myClassMethod)不会更开心吗?由于您根本没有修改方法的行为,我不确定装饰器是否最适合这里。 -
我希望直接从方法定义中看到哪个方法注册到什么事件。