事件处理的扭曲模式

2024-05-15 11:17:05 发布

您现在位置:Python中文网/ 问答频道 /正文

(也欢迎有人协助以更好的形式提出这个问题)

我在看twisted,它实现了一个与互联网完全无关的异步软件。我还得到了一份Twisted网络编程要领的副本,这是相当令人失望的。它,以及几乎所有其他教程,似乎只把twisted当作一个网络客户端,使用内置的事件处理程序,静默地使用难以概括的内置粘合代码。在

对于上下文,我的应用程序希望使用serial/pyserial与硬件设备通信,并提供使用Qt的gui。我甚至还没到开始担心Qt反应器(它看起来又是一个蠕虫病毒的承诺)或移植到windows的地步。在

首先,我使用一个twisted select reactor,我在其中添加了一个Protocol+FileDescriptor来处理udev事件。到目前为止,我的工作是udev事件触发协议中的一个函数(eventReceived)。 以下是协议及其添加到反应器中的方式:

class UdevMonitorListener(Protocol):
    def __init__(self, _reactor=None):
        if _reactor is not None:
            self._reactor = _reactor
        else:
            self._reactor = reactor
        self.subsystem = 'tty'
        self.monitor = None

    def startListening(self):
        logger.info("Starting UdevMonitorListener")

        self.monitor = UdevMonitor(self._reactor, self, self.subsystem)
        self.monitor.startReading()

    def eventReceived(self, action, device):
        if device in connected_devices.udev_ports:
            if action == u'remove':
                connected_devices.remove_by_udev_port(device)
        if action == u'add':
            if is_device_supported_from_udev_port(device):
                if device not in connected_devices.udev_ports:
                    connected_devices.append_by_udev_port(device)


def init(_reactor=None):
    monitor_protocol = UdevMonitorListener(_reactor)
    monitor_protocol.startListening()

函数init()reactor.callWhenRunning()reactor.run()之前调用。eventReceived函数按FileDescriptor的预期调用。如果有帮助的话,我也可以在这里添加代码。在

我想要的是,eventreceived能在反应堆中触发某种事件,其他东西可以对它做出反应。这个代码不应该关心谁在使用它,而那个代码也不应该关心谁在生成它。这些事件之间的间隔会非常少,而且我似乎找不到一个接口可以干净利落地完成这项工作。预计这些事件不会相对频繁地出现,但它们永远不会“结束”。如果要使用deferred,它必须有某种“刷新”的方式来等待下一个事件。处理此类事件的常见模式是什么?在

编辑:

为了子孙后代和其他人的利益,代码的其余部分:

(来自https://gist.github.com/dpnova/a7830b34e7c465baace7

^{pr2}$

或者包含连接的设备和搜索设备的完整模块在https://gist.github.com/chintal/2511459c02a9767deb5d


Tags: 函数代码selfnoneifdevicedef事件
1条回答
网友
1楼 · 发布于 2024-05-15 11:17:05

What I would like is for eventRecieved to trigger some sort of event in the reactor which something else can react to. This code shouldn't care who's consuming this, and that code shouldn't care who's generating it.

在Twisted和by Twisted应用程序中广泛使用的执行此操作的模式是“进行函数调用”(可能是方法调用)。在

反应堆本身并不是一个好的单进程消息总线。没有什么动机尝试把它变成一个函数,因为函数调用本身在一般情况下工作得很好,当你遇到不太常见的、特殊的情况时,实际上很难做出好的结果(一旦你这样做了,你仍然只为《扭曲》的一小部分观众提供服务。在

你的代码已经包含了我所说的那种东西的一个例子。UdevMonitor调用UdevMonitorListener.eventReceived当udev系统中出现某种事件时。在

重复一遍。给您的UdevMonitorListener一个对另一个对象的引用,并在适当的时候调用该对象上的某个方法。例如:

class UdevMonitorListener(object):
    def __init__(self, device_listener, _reactor=None):
        ...
        self.device_listener = device_listener

    def eventReceived(self, ...)
        ...
        self.device_listener.some_device_thing_happened(...)

另请注意,我将基类改为objectProtocolIProtocol实现的一个非常方便的基类,但是UdevMonitorListener不是什么,所以{}不是一个很好的基类选择。在

相关问题 更多 >