如何管理多個唯一的 I/O 裝置實例

2024-05-12 23:16:03 发布

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

我有一个I/O串行设备(一个类,在这里称之为SerialPort),我的程序的其他部分将对其进行读/写SerialPort处理到端口(pyserial)的连接、I/O线程,并作为发布/订阅设计实现,如果有新消息,我程序中的其他类将被回调,或者可以写入新消息。该设备具有>;100条支持的消息和响应,因此采用了发布/订阅设计(不是这个问题的中心,只是想澄清选择)

现在我需要添加2个(或更多)相同的设备。我想做的是让任何观察者打电话,比如:

# The name of the devices and corresponding serial ports are known at run time. So in the program there will be N known devices.

# Where SerialPort("UniqueName1") is connected to port /dev/ttyUSB0
some_observer = Observer(SerialPort("UniqueName1"))
# Where SerialPort("UniqueName2") is connected to port /dev/ttyUSB2
other_observer = Observer(SerialPort("UniqueName2"))
# Here some_observer and random_observer both get the same instance of SerialPort("UniqueName1")
random_observer = Observer(SerialPort("UniqueName1"))

其中,在Observer()中保留了SerialPort的实例(或接口),因此Observer可以写入并注册对SerialPort的回调。我一直在讨论的部分是如何处理对SerialPort(“UniqueName1”)的每次调用都应该返回已经连接的SerialPort对象(假设它已经连接/初始化)。观察者应该只能够说“我想用UniqueName1(或2)与设备通话”

以这种方式,通过在observer中保留两个(或更多)SerialPort引用,我可以拥有两个SerialPort对象的observer。我不需要这样做,但这种设计并不限制我,如果我需要在未来

关于如何在python(2.7)中实现这一点,有什么建议吗?我是python新手,边走边用谷歌搜索。我只需要帮助我将python/伪代码放在下面的位置。我试图将其放入Serialport类中,但SerialPort.__init__(name)不允许我返回已创建的Serialport设备

# Somewhere in the code
sp = SerialPort(name="UniqueName1")
# Now in SerialPort, where all_serial_ports = list of available SerialPorts
for serial_ports in all_serial_ports:
    if serial_ports.name == name:
        return serial_port
# Did not find serial port (need to do something)

Tags: ofthetonamein程序消息port
1条回答
网友
1楼 · 发布于 2024-05-12 23:16:03

虽然可以拦截SerialPort构造函数,以便SerialPort("UniqueName1")返回现有值(如果有),而不是创建新值,1这通常不是您想要做的

最简单的解决方案是只存储串行端口的dict,但这需要每次手动查找:

if "UniqueName1" not in ports:
    ports["UniqueName1"] = SerialPort("UniqueName1")
some_observer = Observer(ports["UniqueName1"])

因此,您可能希望将dict设置为私有,并将访问封装在函数中:

def getport(name):
    if port not in _ports:
        ports[name] = SerialPort(name)
    return ports[name]

现在您只需调用该函数:

some_observer = Observer(getport("UniqueName1"))

您可以将此函数与SerialPortObserver类放在同一个模块中

如果您可能有多个不同的名称到端口映射,那么您可能希望将其包装在一个SerialPortManager类中,该类的实例具有一个self._ports和一个getport方法,但除此之外,您不需要这样做


1.如果你真的想截取构造函数,方法是使用^{}方法。默认实现只返回您类型的新空对象,如果您返回该对象,将调用__init__方法。但是你可以退回任何你想要的东西。这包括不调用super()版本,而是在一些私有目录中查找值。

相关问题 更多 >