小编典典

哪些 Python 包提供独立的事件系统?

all

我知道pydispatcher,但是 Python
必须有其他与事件相关的包。

哪些库可用?

我对作为大型框架一部分的事件管理器不感兴趣,我宁愿使用可以轻松扩展的小型准系统解决方案。


阅读 97

收藏
2022-05-26

共1个答案

小编典典

PyPI 包

截至 2022 年 1 月,这些是 PyPI 上可用的与事件相关的包,按最近的发布日期排序。

还有更多

有很多库可供选择,使用非常不同的术语(事件、信号、处理程序、方法分派、钩子......)。

我试图保持对上述软件包的概述,以及此处答案中提到的技术。

首先,一些术语…

观察者模式

事件系统最基本的风格是“处理程序方法包”,它是观察者模式的简单实现。

基本上,处理程序方法(可调用对象)存储在一个数组中,并在事件“触发”时被调用。

发布-订阅

Observer 事件系统的缺点是您只能在实际的 Event 对象(或处理程序列表)上注册处理程序。因此,在注册时,该事件已经存在。

这就是存在第二种事件系统样式的原因: 发布-
订阅模式
。在这里,处理程序不是在事件对象(或处理程序列表)上注册,而是在中央调度程序上。此外,通知者只与调度员交谈。听什么或发布什么由“信号”决定,它只不过是一个名称(字符串)。

中介者模式

可能也很有趣:中介者模式

挂钩

“挂钩”系统通常用于应用程序插件的上下文中。应用程序包含固定的集成点(挂钩),每个插件都可以连接到该挂钩并执行某些操作。

其他“事件”

注意:threading.Event不是上述意义上的“事件系统”。这是一个线程同步系统,其中一个线程等待直到另一个线程“发出”事件对象的“信号”。

网络消息传递库也经常使用术语“事件”;有时这些在概念上是相似的;有时不是。它们当然可以跨越线程、进程和计算机边界。参见例如
pyzmqpymq
TwistedTornado
geventeventlet

弱引用

在 Python 中,持有对方法或对象的引用可确保它不会被垃圾收集器删除。这可能是可取的,但也可能导致内存泄漏:链接的处理程序永远不会被清理。

一些事件系统使用弱引用而不是常规引用来解决这个问题。

关于各种图书馆的一些话

观察者式事件系统:

  • zope.event展示了它的工作原理(参见Lennart 的回答)。注意:此示例甚至不支持处理程序参数。
  • LongPoke 的“可调用列表”实现表明,这样的事件系统可以通过子类化非常简单地实现list
  • Felk 的变体EventHook还确保了被调用者和调用者的签名。
  • spassig 的 EventHook(Michael Foord 的事件模式)是一个简单的实现。
  • Josip 的 Valued Lessons Event 类基本相同,只是用 aset代替了 alist来存放包,而且__call__它们都是合理的补充。
  • PyNotify在概念上类似,并且还提供了变量和条件的附加概念(“变量更改事件”)。主页无法正常工作。
  • axel基本上是一个处理程序包,具有与线程、错误处理相关的更多功能......
  • python-dispatch要求偶数源类从pydispatch.Dispatcher.
  • buslane是基于类的,支持单个或多个处理程序并促进广泛的类型提示。
  • Pithikos 的Observer/Event是一种轻量级设计。

发布订阅库:

  • blinker有一些漂亮的功能,例如自动断开连接和基于发件人的过滤。
  • PyPubSub是一个稳定的包,并承诺“有助于调试和维护主题和消息的高级功能”。
  • pymitter是 Node.js EventEmitter2 的 Python 端口,提供命名空间、通配符和 TTL。
  • PyDispatcher似乎强调多对多发布等方面的灵活性。支持弱引用。
  • louie是一个重新设计的 PyDispatcher,应该“在各种环境中”工作。
  • pypydispatcher基于(你猜对了......)PyDispatcher 并且也适用于 PyPy。
  • django.dispatch是一个重写的 PyDispatcher,“接口更有限,但性能更高”。
  • pyeventdispatcher基于 PHP 的 Symfony 框架的事件调度器。
  • 调度程序是从 django.dispatch 中提取的,但已经相当老了。
  • Cristian Garcia 的EventManger2)是一个非常简短的实现。

其他:

  • pluggy包含一个由pytest插件使用的钩子系统。
  • RxPy3实现了 Observable 模式并允许合并事件、重试等。
  • Qt 的信号和插槽可从PyQtPySide2 获得。它们在同一个线程中使用时作为回调,或者作为两个不同线程之间的事件(使用事件循环)。Signals 和 Slots 的局限性在于它们只能在派生自QObject.
2022-05-26