with 語句是 Pyhton 上的一種簡化語法,with 語句是從 Python 2.5 開始引入的一種與異常處理相關的功能。
with 語句適用於對資源進行訪問的場合,確保不管使用過程中是否發生異常都會執行必需的“清理”操作,釋放資源。比如檔案使用後自動關閉、資料庫的開啟和自動關閉等。
語法格式是這樣的:
with open('test', 'w') as f:
f.write('Python大法好')複製程式碼
通過 with 語句在編寫程式碼時,會使程式碼變得更加簡潔。在編寫程式碼時,不用再顯示的去關閉檔案。
語句的執行過程:
- 在執行 with 語句時,首先執行 with 後面的 open 程式碼
- 執行完程式碼後,會將程式碼的結果通過 as 儲存到 f 中
- 然後在下面實現真正要執行的操作
- 在操作後面,並不需要寫檔案的關閉操作,檔案會在使用完後自動關閉
實際上,在檔案操作時,並不是不需要寫檔案的關閉,而是檔案的關閉操作在 with 的上下文管理器中的協議方法裡已經寫好了。
當檔案操作執行完成後, with語句會自動呼叫上下文管理器裡的關閉語句來關閉檔案資源。
with 語句在執行時,需要呼叫上下文管理器中的 __enter__ 和 __exit__ 兩個方法。
__enter__ 方法會在執行 with 後面的語句時執行,一般用來處理操作前的內容。比如一些建立物件,初始化等。
__exit__ 方法會在 with 內的程式碼執行完畢後執行,一般用來處理一些善後收尾工作,比如檔案的關閉,資料庫的關閉等。
在自定義上下文管理器時,只需要在類中實現 __enter__ 和 __exit__ 兩個方法即可。
模擬檔案開啟過程:
import time
class MyOpen(object):
def __init__(self,file, mode):
self.__file = file
self.__mode = mode
def __enter__(self):
print('__enter__ run ... 開啟檔案')
self.__handle = open(self.__file, self.__mode)
return self.__handle
def __exit__(self, exc_type, exc_val, exc_tb):
print('__exit__... run ... 關閉檔案')
self.__handle.close()
with MyOpen('test','w') as f:
f.write('Python 大法好')
time.sleep(3)
print('over')
複製程式碼
程式執行結果:
__enter__ run ... 開啟檔案
__exit__ run ... 關閉檔案
over
複製程式碼
__exit__ 方法中有三個引數,用來接收處理異常,如果程式碼在執行時發生異常,異常會被儲存到這裡。
- exc_type : 異常型別
- exc_val : 異常值
- exc_tb : 異常回溯追蹤
異常資訊的處理
當with中執行的語句發生異常時,異常資訊會被髮送到 __exit__ 方法的引數中,這時可以根據情況選擇如何處理異常。
class MyCount(object):
def __init__(self, x, y):
self.__x = x
self.__y = y
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 通過 引數接收到的值,來判斷程式執行是否出現異常
# 如果是 None ,說明沒有異常
if exc_type == None:
print('計算正確執行')
else:
# 否則出現異常,可以選擇怎麼處理異常
print(exc_type,exc_val)
# 返回值決定了捕獲的異常是否繼續向外丟擲
# 如果是 False 那麼就會繼續向外丟擲,程式會看到系統提示的異常資訊
# 如果是 True 不會向外丟擲,程式看不到系統提示資訊,只能看到else中的輸出
return True
def div(self):
print(self.__x / self.__y)
with MyCount(6, 0) as mc:
mc.div()
複製程式碼
在 __exit__函式執行異常處理時,會根據函式的返回值決定是否將系統丟擲的異常繼續向外丟擲。
如果返回值為 False 就會向外丟擲,使用者就會看到。 如果返回值為 True 不會向外丟擲,可以將異常顯示為更加友好的提示資訊。