一、簡介
with是從Python 2.5 引入的一個新的語法,更準確的說,是一種上下文的管理協議,用于簡化try…except…finally的處理流程。with通過__enter__方法初始化,然后在__exit__中做善后以及處理異常。對于一些需要預先設置,事后要清理的一些任務,with提供了一種非常方便的表達。
with的基本語法如下,EXPR是一個任意表達式,VAR是一個單一的變量(可以是tuple),”as VAR”是可選的。
二、實現方式
根據前面對with的翻譯可以看到,被with求值的對象必須有一個__enter__方法和一個__exit__方法。稍微看一個文件讀取的例子吧,注意在這里我們要解決2個問題:文件讀取異常,讀取完畢后關閉文件句柄。用try…except一般會這樣寫:
def __init__(self, name):
self.handle = open(name)
def __enter__(self):
return self.handle
def __exit__(self, type, value, trackback):
self.handle.close()
with opened('/tmp/a.txt') as f:
for line in f.readlines():
print(line)
如果你不喜歡定義class,還可以用Python標準庫提供的contextlib來實現:
@contextmanager
def opened(name):
f = open(name)
try:
yield f
finally:
f.close()
with opened('/tmp/a.txt') as f:
for line in f.readlines():
print(line)
三、應用場景
廢話了這么多,那么到底那些場景下該使用with,有沒有一些優秀的例子?當然啦,不然這篇文章意義何在。以下摘自PEP 343。
一個確保代碼執行前加鎖,執行后釋放鎖的模板:
with locked(myLock):
# Code here executes with myLock held. The lock is
# guaranteed to be released when the block is left (even
# if via return or by an uncaught exception).
with opened(filename, "w") as f:
with stdout_redirected(f):
print "Hello world"
四、總結
with是對try…expect…finally語法的一種簡化,并且提供了對于異常非常好的處理方式。在Python有2種方式來實現with語法:class-based和decorator-based,2種方式在原理上是等價的,可以根據具體場景自己選擇。
with最初起源于一種block…as…的語法,但是這種語法被很多人所唾棄,最后誕生了with,關于這段歷史依然可以去參考PEP-343和PEP-340
新聞熱點
疑難解答
圖片精選