2011-10-25 55 views
1

下面是一個合理的方法嗎?串口上下文管理器

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

如果你運行這段代碼:

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__小號被調用,即使一個引發錯誤(帶有ABBA)。

如果您從一個集體__exit__中調用__exit__ s,如果第一個發生錯誤,第二個__exit__將不會被調用。

改爲使用嵌套上下文管理器,假設您的固定數目較少。

+0

我同意嵌套的上下文管理器將是一個比單個串行端口管理器更好的解決方案來覆蓋多個SerialPort實例。 –

2

這個怎麼樣?

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

in是在python reserved word,並用它作爲一個變量名將導致一個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在這一個。他的建議對你的情況好得多。

+0

因爲他在嘗試關閉端口時可能並不擔心錯誤,只是在使用它的時候,這在實踐中很可能是很好的,如果有足夠的端口不想在'with'中指定它們, ,因爲你可以用'serial_ports(* port_list)作爲端口:'用這個方法。 – agf