2014-01-06 71 views
1

我想找到一個優雅的方式來做到以下幾點:使用Python中的資源優雅的方式?

try: 
    with some_resource: 
     # got it 
     do_something() 

except ResourceUnavailableError: 
    # didn't get it 
    do_something_else() 

此:

  1. 試圖獲取資源
  2. 上的成功,它的東西,然後正確地釋放資源
  3. 失敗,它做別的事

雖然沒有許多代碼行,我發現如果我必須繼續在很多不同的地方寫這篇文章,那就不是很優雅。

我幾乎希望我能寫出如下的東西(我知道這是不是真正的Python代碼):

with some_resource: 
    # got it 
    do_something() 

# an optional else 
else: 
    # didn't get it 
    do_something_else() 

有誰知道,如果有可能沿着寫在Python中類似的規定? 謝謝!

回答

4

不,with沒有else塊。但是你可以編寫處理else屬於你自己的情況管理器:

from contextlib import contextmanager 

@contextmanager 
def handle_unavailable(resource, exception, exception_handler): 
    try: 
     with resource: 
      yield resource 
    except exception: 
     exception_handler() 

,並使用它像這樣到處爲:

with handle_unavailable(some_resource, ResourceUnavailableError, do_something_else): 
    do_something() 

所以如果ResourceUnavailableErrorwith塊凸起,do_something_else被調用您。

這使得使用@contextlib.contextmanager() decorator,這使得編寫自己的上下文管理器幾乎微不足道。

+0

感謝您的答覆!但是......我不確定這是否有效。我試着編碼,當沒有例外時,一切都很好。但是,如果有異常升高,然後運行exception_handler()後,我得到了:RuntimeError:發電機沒有屈服。 – moomima

+0

順便說一句,這個錯誤導致我到另一個,類似的帖子在這裏,這也似乎在苦難已經結束:P http://stackoverflow.com/questions/4314338/can-i-use-python-with-statement-爲條件執行 – moomima

+0

啊,麪包屑。事實上,我認爲你的意思是在'with'塊中引發異常,而不是創建資源。 –