2011-10-25 2 views
1

다음과 같은 적절한 방법이 있습니까? SerialPortsSerialPort 컨텍스트 관리자 인터페이스를 구현직렬 포트 콘텍스트 관리자

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

    # use in and out 

.

SerialPorts.exit() 루프는 추가 직렬 포트를 통해 exit()을 호출합니다. SerialPortexit()은 직렬 포트를 닫습니다.

더 좋은 방법이 있나요?

답변

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__의 하나가 오류가 발생하는 경우에도 호출되는 것을 볼 수 있습니다 (와 하나 AABB 전).

__exit__을 모두 하나의 집합체 __exit__에서 호출하는 경우 첫 번째 오류가 발생하면 두 번째 __exit__이 호출되지 않습니다.

작은 고정 숫자가 있다고 가정 할 때 중첩 된 컨텍스트 관리자를 대신 사용하십시오.

+0

중첩 된 컨텍스트 관리자가 SerialPort의 여러 인스턴스를 다루기 위해 단일 SerialPorts 관리자보다 더 나은 솔루션이라고 동의합니다. –

2

어때?

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

in 파이썬에서 reserved word이며, 변수 이름으로 사용하면 구문 에러가 발생할 것이다.


편집 : 여기 (안된) 하나의 가능한 구현의 :

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하는 연기. 그의 제안은 당신의 경우에 훨씬 좋습니다.

+0

그는 포트를 닫으려고 할 때 오류를 걱정하지 않으므로 사용하는 동안 오류가 발생할 가능성이 거의 없으므로 포트가 충분하여'with ' 이 방법으로'serial_ports (* port_list) as ports :'를 할 수있다. – agf