如何管理I / O设备的多个唯一实例

时间:2018-06-18 23:22:40

标签: python python-2.7

我有一个I / O串行设备(一个类,在这里调用SerialPort),我的程序的其他部分将读/写。 SerialPort处理与端口的连接(pyserial),I / O的线程,并作为pub / sub设计实现,如果有新消息,我的程序中的其他类会被回调,或者可以写新消息。该设备具有> 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对象。我不需要这样做,但如果我将来需要这个设计并不限制我。

有关如何在python(2.7)中执行此操作的任何建议吗?我是蟒蛇新手,谷歌去看看。我只需要在下面放置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)

1 个答案:

答案 0 :(得分:1)

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

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

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._portsgetport方法,但除此之外你不需要那个。

1.如果你确实想拦截构造函数,那么使用__new__方法的方法就是这样。默认实现只返回您的类型的新空对象,如果您返回该对象,则会调用__init__方法。但是你可以返回任何你想要的东西。其中包括不调用super()版本,而是在某个私人字典中查找值。