class Event(list):
"""Event subscription.
A list of callable objects. Calling an instance of this will cause a
call to each item in the list in ascending order by index.
Example Usage:
>>> def f(x):
... print 'f(%s)' % x
>>> def g(x):
... print 'g(%s)' % x
>>> e = Event()
>>> e()
>>> e.append(f)
>>> e(123)
f(123)
>>> e.remove(f)
>>> e()
>>> e += (f, g)
>>> e(10)
f(10)
g(10)
>>> del e[0]
>>> e(2)
g(2)
"""
def __call__(self, *args, **kwargs):
for f in self:
f(*args, **kwargs)
def __repr__(self):
return "Event(%s)" % list.__repr__(self)
class MyBroadcaster()
def __init__():
self.onChange = EventHook()
theBroadcaster = MyBroadcaster()
# add a listener to the event
theBroadcaster.onChange += myFunction
# remove listener from the event
theBroadcaster.onChange -= myFunction
# fire event
theBroadcaster.onChange.fire()
我们将删除对象中所有侦听器的功能添加到Michaels类中,结果是:
class EventHook(object):
def __init__(self):
self.__handlers = []
def __iadd__(self, handler):
self.__handlers.append(handler)
return self
def __isub__(self, handler):
self.__handlers.remove(handler)
return self
def fire(self, *args, **keywargs):
for handler in self.__handlers:
handler(*args, **keywargs)
def clearObjectHandlers(self, inObject):
for theHandler in self.__handlers:
if theHandler.im_self == inObject:
self -= theHandler
我一直是这样做的:
然而,和我看到的其他东西一样,这里没有自动生成的pydoc,也没有签名,这真的很糟糕。
我们使用Michael Foord在他的Event Pattern中建议的EventHook:
只需将EventHook添加到您的类中:
我们将删除对象中所有侦听器的功能添加到Michaels类中,结果是:
总结以下答案中提到的各种事件系统:
事件系统最基本的样式是“处理程序方法包”,它是Observer pattern的简单实现。基本上,处理程序方法(callables)存储在一个数组中,并且在事件“激发”时分别被调用。
list
,这样的事件系统可以实现得非常少。set
而不是list
来存储包,并且实现了__call__
,这两个都是合理的添加。这些事件系统的缺点是只能在实际的事件对象(或处理程序列表)上注册处理程序。 因此在注册时,该事件已经需要存在。
这就是为什么存在第二种类型的事件系统:即publish-subscribe pattern。 在这里,处理程序不在事件对象(或处理程序列表)上注册,而是在中央调度程序上注册。同时,通知程序只与调度程序对话。监听什么或发布什么由“signal”决定,它只不过是一个名称(字符串)。
QObject
的类的对象中工作。注意:threading.Event不是上述意义上的“事件系统”。这是一个线程同步系统,其中一个线程等待另一个线程向事件对象发出“信号”。
注意:上面还没有包括pypydispatcher,python-dispatch和pluggy的“钩子系统”可能也很有趣。
相关问题 更多 >
编程相关推荐