Менеджер контекста последовательных портов - PullRequest
1 голос
/ 25 октября 2011

Является ли следующий подход разумным?

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

    # use in and out

, где SerialPorts и SerialPort реализуют интерфейс диспетчера контекста.

SerialPorts.exit() проходит через добавленные последовательные порты, вызывая ихexit().SerialPort s exit() закрывает последовательный порт.

Есть ли лучший способ сделать это?

Ответы [ 2 ]

2 голосов
/ 25 октября 2011

Если вы запустите этот код:

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 и B до A).

Если вы вызываете оба __exit__ s из одного коллектива __exit__, если первый имеет ошибку, второй __exit__ не будет вызван.

Вместо этого используйте вложенные контекстные менеджеры, предполагая, что у вас их небольшое фиксированное число.

2 голосов
/ 25 октября 2011

Как насчет этого?

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

in - это зарезервированное слово в python, и использование его в качестве имени переменной приведет к ошибке SyntaxError.


Редактировать : Вот одна из возможных реализаций (не проверено):

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 на этот. Его предложение намного лучше для вашего случая.

...