背景
有一些任務,可能事先需要設置,事后做清理工作。對於這種場景,Python的with語句提供了一種非常方便的處理方式。
with如何工作?
- 緊跟with后面的語句被求值后,返回對象的 __enter__() 方法被調用,這個方法的返回值將被賦值給as后面的變量。
- 當with后面的代碼塊全部被執行完之后,將調用前面返回對象的 __exit__()方法。
例子
#!/usr/bin/env python
class Test(obj):
def __enter__(self):
print "In __enter__()"
- return "test_with"
def __exit__(self, type, value, trace):
print "In __exit__()"
def get_example():
return Test()
with get_example() as example:
print "example:", example
大家可以做下實驗看下輸出.
__exit__ 方法有三個參數 val, type 和 trace。 這些參數在異常處理中相當有用。
實際上,在with后面的代碼塊拋出任何異常時,__exit__() 方法被執行。正如例子所示,異常拋出時,與之關聯的type,value和stack trace傳給 __exit__() 方法,因此拋出的XX異常被打印出來了。開發庫時,清理資源,關閉文件等等操作,都可以放在 __exit__ 方法當中。
另外,__exit__ 除了用於tear things down,還可以進行異常的監控和處理,注意后幾個參數。要跳過一個異常,只需要返回該函數True即可。
下面的樣例代碼跳過了所有的TypeError,而讓其他異常正常拋出。
def __exit__(self, type, value, traceback):
- return isinstance(value, TypeError)
__exit__ 函數可以進行部分異常的處理,如果我們不在這個函數中處理異常,他會正常拋出,這時候我們可以這樣寫
try:
with open( "a.txt" ) as f :
do something
except xxxError:
do something about exception