串口上下文管理器

1 投票
2 回答
1709 浏览
提问于 2025-04-17 04:58

以下这种做法合理吗?

with SerialPorts() as serial_ports:
    in= SerialPort("COM1")
    serial_ports.add(in)
    out = SerialPort("COM2")
    serial_ports.add(out)

    # use in and out

这里的 SerialPortsSerialPort 实现了上下文管理器的接口。

SerialPorts.exit() 会遍历所有添加的串口,并调用它们的 exit() 方法。SerialPortexit() 方法则是用来关闭串口的。

有没有更好的方法来实现这个呢?

2 个回答

2

这样怎么样?

with SerialPorts("COM1", "COM2") as (inport, outport):
    # use inport and outport

in 是 Python 里的一个 保留字,如果你把它当作变量名来用,就会出现语法错误。


编辑:这里有一个可能的实现方式(没有测试过):

import serial
from contextlib import contextmanager 

@contextmanager
def serial_ports(*args):
    ports = [serial.Serial(arg) for arg in args]
    try:
        yield ports
    finally:
        for port in ports:
            port.close()

with serial_ports('COM1', 'COM2') as (inp, outp):
    print 'inp:', inp.isOpen(), 'outp:', outp.isOpen()

print 'inp:', inp.isOpen(), 'outp:', outp.isOpen()

不过我还是听 @agf 的建议。他的方案对你的情况来说要好得多。

2

如果你运行这段代码:

class A(object):
    def __enter__(self):
        return self
    def __exit__(self, *args):
        print "exit", self

class B(object):
    def __enter__(self):
        return self
    def __exit__(self, *args):
        print "exit", self
        raise Exception

with A() as a, B() as b:
    pass

你会发现即使其中一个出现错误,两个 __exit__ 还是都会被调用(无论是先调用 A 还是先调用 B)。

但是,如果你从一个统一的 __exit__ 调用这两个 __exit__,如果第一个出现错误,第二个 __exit__ 就不会被调用了。

所以,建议使用嵌套的上下文管理器,前提是你有的数量比较少且固定。

撰写回答