跳至正文

Python 的事件处理

在开发比较复杂的程序时,通常会采用基于事件的驱动逻辑,例如在 H5 项目中经常使用的 js-signal,那么在 Python 中有没有类似的处理方式呢?

PyDispatcher

这个 PyDispatcher 是目前找到一个比较好用的处理基于事件逻辑的工具,下面弄个简单的例子来说明:

global_data.py

SIGNAL_DO_BAR = 'signal-do-bar'
SINGAL_DO_FOO = 'signal-do-foo'

sender = object()

首先定义了一个 Global Data,用来存储一些全局可用的变量;SIGNAL_DO_BARSIGNAL_DO_FOO 分别是两个事件的名称;sender 后续供 dispather 使用。

my_class.py

class MyClass:
    def __init__(self, name):
        self.name = name

    def doBar(self, value):
        print(f'{self.name} do bar, value: {value}')

    def doFoo(self, value):
        print(f'{self.name} do foo, value: {value}')

定义了一个简单的 My Class,有 doBardoFoo 两个简单的实例方法。

test.py

from pydispatch import dispatcher

import global_data as GlobalData

from my_class import MyClass

myClass = MyClass('my-class')

dispatcher.connect(myClass.doBar, GlobalData.SIGNAL_DO_BAR, GlobalData.sender)
dispatcher.connect(myClass.doFoo, GlobalData.SINGAL_DO_FOO, GlobalData.sender)

dispatcher.send(GlobalData.SIGNAL_DO_BAR, GlobalData.sender, '123')
dispatcher.send(GlobalData.SINGAL_DO_FOO, GlobalData.sender, 456)

上面诠释了 dispatcher 的用法,主要是 connect 和 send 方法;但是这样写略显麻烦,所以参照之前 js-signal 的经验,有了第二种写法:

from pydispatch import dispatcher

import global_data as GlobalData

from my_class import MyClass

myClass = MyClass('my-class')

def handleGlobalData(e, value):
    if e == GlobalData.SIGNAL_DO_BAR:
        myClass.doBar(value)
    elif e == GlobalData.SINGAL_DO_FOO:
        myClass.doFoo(value)

dispatcher.connect(receiver=handleGlobalData, signal=dispatcher.Any, sender=GlobalData.sender)

dispatcher.send(signal=dispatcher.Any, sender=GlobalData.sender, e=GlobalData.SIGNAL_DO_BAR, value='123')

dispatcher.send(dispatcher.Any, GlobalData.sender, GlobalData.SINGAL_DO_FOO, 456)

在第二种方法中,因为并不关心具体的 singal 是什么,所以 dispatcher 的 connect 和 send 中的 signal 参数都为 dispatcher.Any;然后 send 时,将具体的事件名称通过参数的形式发送。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注