2014-04-01 33 views
1

關於Python中with語句的兩個問題。他們來自現實生活中的問題,所以我保持真實。我正在處理一個夾管閥以控制管道中的流量。關於在Python中使用with語句的技巧

程序驅動閥與一類看似是:

class Valve(object): 
    """This class drives a pinch valve.""" 
    def __init__(self): 
     self.close() 
    def open(self): 
     print('Open the valve.') 
     self.state = 'opened' 
    def close(self): 
     print('Close the valve.') 
     self.state = 'closed' 
    def print_state(self): 
     print('The valve is '+self.state+'.') 

對於某些操作,我需要的東西與文件with語句確實(該文件是在年底或如果有錯誤關閉上升),所以我增加了一個功能,該類閥門和其他類:

def opened(self): 
     return ContextManagerOpenedValve(self) 

class ContextManagerOpenedValve(object): 
    def __init__(self, valve): 
     self.valve = valve 
    def __enter__(self): 
     self.valve.open() 
     return self.valve 
    def __exit__(self, type, value, traceback): 
     self.valve.close() 

那麼這些行似乎工作如我所料:

def do_something(): 
    print('For the sake of simplicity, this function does nothing.') 

valve = Valve() 

valve.print_state() 
with valve.opened(): 
    valve.print_state() 
    do_something() 
valve.print_state() 

我的第一個問題:獲得這樣結果的正確方法是什麼?我有權使用with聲明嗎?我無法以更聰明的方式做到這一點,而無需定義類ContextManagerOpenedValve?

然後,我需要做這樣的事情: USE_VALVE =假#或USE_VALVE =真

if USE_VALVE: 
    with valve.opened(): 
     do_something() 
else: 
    do_something() 

我不喜歡,因爲功能do_something這個解決方案是無論如何運行,因此這將是好得多,以避免重複「do_something()」。

我的第二個問題:有沒有辦法獲得相同的結果沒有 重複do_something()兩次?

+1

請保持您的問題,每一個崗位;例如,條件上下文管理器部分是重複的。 –

回答

0

當然,你可以做到這一點,像這樣:

def valve_control(valve, use_value=False): 
    if use_value: 
    return ContextManagerOpenedValve(valve) 
    else: 
    return SomeFakeContextManager() 

然後你的電話看起來像:

with valve_control(value, USE_VALVE): 
    do_something()