關於python中with as 的使用
其實with as 是python的控制流語句,像if ,while等的,只是比那個難理解罷了
首先我先摘抄一段別人的程式碼大體上給你們理解理解
首先請看下邊的解釋:
是不是不明白,其實我看了也覺得不明白,很暈,很繞,
下面給大家解釋一下,所謂上下文管理協議,其實是指with後面跟的ecception一般是一個類的實體,這個類的實體要包含__enter__和__exit__函式的定義才行
這個類嗎 想必大家都知道了,還有try/finally try/except等等這些異常處理方法我就不解釋了。我就直奔正題。對於__enter__和__exit__方法這兩個方法被稱為 魔術方法 。其實是python的內建函式
class Closer:
def __init(self,obj):
self.obj = obj
def __enter__(self):
return self.obj
def __exit__(sekf,exception_type,exception_val,trace)
try:
self.obj.close()
except AttributeError:
print "NOt closable"
return True
這是才定義一個叫做Closer的類,我們看一下這個類中有什麼
1. 一個__init__方法,__init__方法是個魔術方法,就是內建方法,在類初始化物件的時候被執行,起到初始化的作用
2. 一個__enter__方法,專門用於with 的一個內建方法,他的返回值要跟with as 語句中跟在as 後邊的variable.
3. 一個__exit__方法,用於with 語句的一個內建方法當with as語句中的with-block被執行或者終止後,這個類的物件應該做什麼,如果這個程式碼執行成功,則exception_type, exception_val。trace輸入值都是空,如果程式碼出錯了,就會變成像try/exception/finally語句一樣
with exception as varable with-block
它的執行過程是:
首先執行exception 裡面的__enter__函式,它的返回值會賦給as 後邊的variable。像讓他返回什麼就返回什麼,只要你知道怎麼處理就行了,如顆不寫 as variable ,返回值就會被忽略。然後,開始執行with-block中的語句,不論成功失敗(比如發生異常,錯誤,設定sys.exit()),在with-block執行完成後,會執行expection中的__exit__函式
然後可能有的同學會問,這又跟try/finally有什麼關係呢,其實這樣的過程等價與
try:
執行__enter__的內容
執行 with_block
finally:
執行__exit__內容
這就應該懂了吧 然後我們這時候再使用網上那些說的很迷的例子看一看 你就會明白了
class Sample(object): # object類是所有類最終都會繼承的類
def __enter__(self): # 類中函式第一個引數始終是self,表示建立的例項本身
print("In __enter__()")
return "Foo"
def __exit__(self, type, value, trace):
print("In __exit__()")
def get_sample():
return Sample()
with get_sample() as sample:
print("sample:", sample)
然後我們看一下結果是不是和你想的是一樣的
In __enter__()
sample: Foo
In __exit__()
我們然後來分析一下程式是怎麼執行的
- 首先我們呼叫get_sample()函式,返回Sample類
- 執行Sample類中的__enter__()方法,列印"in__enter()"字串,並將字串“Foo”賦值給 as 後邊的sample變數;
- 執行with__block程式碼塊,即列印"sample: %s"字串,結果為“sample Foo”
- 執行with__block程式碼塊結束後,返回Sample()類,執行類方法__exit__().因為在執行with__block程式碼塊時並沒有錯誤返回,所以type,value,trace這三個argument都沒有值,直接列印print"in__exit__()"