为 class 方法使用 pydispatch 和装饰器
Using pydispatch and decorators for class methods
我正在尝试一些相当简单的事情。我想编写一个装饰器,它使用 pydispatcher 在事件处理程序中转换 class 方法。这是我的基本方法:
from pydispatch.dispatcher import connect,send,Any
SIGNAL = "test"
def triggered(func):
connect(func,signal=SIGNAL,sender = Any)
return func
class P(object):
@triggered
def a(self,*args,**kwargs):
print "yay"
if __name__ == "__main__":
p = P()
send(signal=SIGNAL,sender="")
这会引发错误:
Traceback (most recent call last):
File "util.py", line 35, in <module>
send(signal=SIGNAL,sender="")
File "/usr/local/lib/python2.7/dist-packages/pydispatch/dispatcher.py", line 338, in send
**named
File "/usr/local/lib/python2.7/dist-packages/pydispatch/robustapply.py", line 55, in robustApply
return receiver(*arguments, **named)
TypeError: a() takes at least 1 argument (0 given)
有什么想法吗?
您在 class 中注册了一个 函数。这意味着 只是 函数被注册,而不是绑定方法。函数未绑定到实例,因此没有传入 self
参数。
您不能希望在 class 定义中的常规方法上使用装饰器,因为当时所需的上下文(实例)不可用。
您必须先创建一个实例,然后注册绑定到该实例的方法才能工作:
class P(object):
def a(self, *args, **kwargs):
print "yay"
if __name__ == "__main__":
p = P()
triggered(p.a)
send(signal=SIGNAL,sender="")
现在triggered()
注册p.a
绑定方法;调用该方法将在调用时将 p
作为 self
参数传递。
您也可以将 a
方法设为 static 或 class 方法。静态方法本质上只是一个函数;它从不接受 self
参数。这意味着您可以将其注册为信号处理程序,但您永远无法获得使用 class:
的好处
class P(object):
@staticmethod
@triggered
def a(*args, **kwargs):
print "yay"
如果您将其设为 class 方法,您将获得传入的 class(仍然不是实例),并且您将 拥有 在 class 之外进行注册以确保您获得绑定方法:
class P(object):
@classmethod
def a(cls, *args, **kwargs):
print "yay"
triggered(P.a)
我正在尝试一些相当简单的事情。我想编写一个装饰器,它使用 pydispatcher 在事件处理程序中转换 class 方法。这是我的基本方法:
from pydispatch.dispatcher import connect,send,Any
SIGNAL = "test"
def triggered(func):
connect(func,signal=SIGNAL,sender = Any)
return func
class P(object):
@triggered
def a(self,*args,**kwargs):
print "yay"
if __name__ == "__main__":
p = P()
send(signal=SIGNAL,sender="")
这会引发错误:
Traceback (most recent call last):
File "util.py", line 35, in <module>
send(signal=SIGNAL,sender="")
File "/usr/local/lib/python2.7/dist-packages/pydispatch/dispatcher.py", line 338, in send
**named
File "/usr/local/lib/python2.7/dist-packages/pydispatch/robustapply.py", line 55, in robustApply
return receiver(*arguments, **named)
TypeError: a() takes at least 1 argument (0 given)
有什么想法吗?
您在 class 中注册了一个 函数。这意味着 只是 函数被注册,而不是绑定方法。函数未绑定到实例,因此没有传入 self
参数。
您不能希望在 class 定义中的常规方法上使用装饰器,因为当时所需的上下文(实例)不可用。
您必须先创建一个实例,然后注册绑定到该实例的方法才能工作:
class P(object):
def a(self, *args, **kwargs):
print "yay"
if __name__ == "__main__":
p = P()
triggered(p.a)
send(signal=SIGNAL,sender="")
现在triggered()
注册p.a
绑定方法;调用该方法将在调用时将 p
作为 self
参数传递。
您也可以将 a
方法设为 static 或 class 方法。静态方法本质上只是一个函数;它从不接受 self
参数。这意味着您可以将其注册为信号处理程序,但您永远无法获得使用 class:
class P(object):
@staticmethod
@triggered
def a(*args, **kwargs):
print "yay"
如果您将其设为 class 方法,您将获得传入的 class(仍然不是实例),并且您将 拥有 在 class 之外进行注册以确保您获得绑定方法:
class P(object):
@classmethod
def a(cls, *args, **kwargs):
print "yay"
triggered(P.a)