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

Python 如何管理I/O设备的多个唯一实例,python,python-2.7,Python,Python 2.7,我有一个I/O串行设备a类,在这里调用SerialPort,我的程序的其他部分将对其进行读/写。SerialPort处理到端口pyserial的连接,即I/O线程,并作为发布/订阅设计实现,如果有新消息,我程序中的其他类将被回调,或者可以写入新消息。该设备支持100条以上的消息和响应,因此发布/订阅设计不是这个问题的中心,只是想澄清选择 现在我需要添加2个或更多相同的设备。我想做的是让任何观察者打电话,比如: # The name of the devices and corresponding

我有一个I/O串行设备a类,在这里调用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"))
其中,在观察器中保留了SerialPort的实例或接口,因此观察器可以写入并注册对SerialPort的回调。我一直关注的部分是如何处理对SerialPortUniqueName1的每次调用都应该返回已经连接的SerialPort对象(假设其已连接/初始化)。观察者应该能够说我想和一个有UniqueName1或UniqueName2的设备通话

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

关于如何在Python2.7中实现这一点,有什么建议吗?我是python新手,边走边用谷歌搜索。我只需要帮助我将python/伪代码放在下面的位置。我试图将其放入Serialport类中,但Serialport。\ uu init\ uu 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)
虽然可以截取SerialPort构造函数,以便SerialPortUniqueName1返回现有值(如果有),而不是创建新值,但通常情况下,这不是您想要做的

最简单的解决方案是只存储串行端口的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"))
现在您只需调用该函数:

def getport(name):
    if port not in _ports:
        ports[name] = SerialPort(name)
    return ports[name]
some_observer = Observer(getport("UniqueName1"))
您可以将此函数与SerialPort或Observer类放在同一个模块中

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


一,。如果你真的想截取构造函数,方法就是使用一个方法。默认实现只返回您类型的一个新空对象,如果您返回该对象,将调用您的_init__方法。但是你可以退回任何你想要的东西。这包括不调用超级版本,而是在某个私有目录中查找值。

您真的希望由SerialPort类的构造函数来处理,而不是调用SerialPorts或SerialPortManager类的某个实例,或者只是在公共目录中查找吗?@abarnert我不确定,不知道什么最有意义。如果它是由SerialPortManager处理的,它会像SerialPortManager.get_serial_portUniqueName1一样吗?是的,我可能应该保持它的简单,而不是过于复杂。然而,我将检查“新的”以供我自己学习。@user2840470使用“新的”需要注意的一件棘手的事情是,它是否调用“初始化”完全取决于您返回的是否为instanceobj、cls,而不是您是否通过super检索它。最简单的解决方案通常是使uuu init uuuuuuuuuuuuuuuu幂等,甚至是一个no-op,并在uuuu new uuuuuuuuu内进行初始化。如果您搜索单例库,您应该会找到一些这样的例子。