有一些任務, 可能事先需要設定, 事後做清理工作. 對於這種場景, python的with語句提供了一種非常方變的處理方式, 乙個很好的例子是檔案處理. 你需要獲取乙個檔案的控制代碼, 從檔案中讀取資料, 然後關閉檔案控制代碼. 如果不用with語句, **如下:
file = open("/tmp/foo.txt")
data =file.read()
file.close()
這裡有兩個比較煩人的地方, 一是可能忘記關閉控制代碼, 而是檔案讀取資料時發生異常, 卻沒有進行任何處理(檔案讀取資料發生異常時, 後面的**將得不到執行, 因此獲取的檔案控制代碼不能正常關閉), 下面的**可以解決這個問題:
file = open("/tmp/foo.txt")
try:
data =file.read()
finally
: file.close()
雖然這段**工作良好, 但是太冗長了, 這時候就是with出馬的時候了. 用with寫法, 除了擁有更優雅的語法, 還能夠處理異常. 下面是上面**的with寫法:
with open("/tmp/foo.txt
") as file:
data = file.read()
它是怎麼工作的呢?
基本思想是with關鍵字後面的語句生成的物件必須實現兩個方法, __enter__()和__exit__()方法. with關鍵字後面的語句被求值後, 返回物件的__enter__()方法被呼叫, 這個方法的返回值被賦值為as關鍵字後面的變數. 當with語句後面的**全部執行完之後, 將呼叫前面返回物件的__exit__()物件. 下面這個例子可以說明with語句如何工作:
classsample:
def__enter__
(self):
"in __enter__()
"return
"foo
"def
__exit__
(self, type, value, trace):
"in __exit__()
"def
get_sample():
return
sample()
with get_sample() as sample:
"sample:
", sample
上面的**執行結果如下:
in __enter__()sample: foo
in __exit__()
正如你所看到的,
1. __enter__()方法被執行
2. __enter__()方法返回的值(這裡是"foo")被賦值給變數sample
3. 執行with語句後面的**塊, 列印sample變數的值
4. __exit__()方法被執行
with語句真正強大之處在於它可以處理異常, 你應該已經注意到了sample類的__exit__()方法有三個引數, 分別是type, value和trace. 這三個引數在異常處理時非常有用, 我們來改一下**, 看看到底是怎麼工作的:
classsample:
def__enter__
(self):
return
self
def__exit__
(self, type, value, trace):
"type:
", type
"value:
", value
"trace:
", trace
defdo_something(self):
bar = 1/0
return bar + 10
defget_sample():
return
sample()
with get_sample() as sample:
sample.do_something()
執行後的結果如下:
type: 'exceptions.zerodivisionerror
'>value: integer division or modulo by zero
trace:
object at 0xb749c11c>traceback (most recent call
last
): file
"a.python
", line 14, in
sample.do_something()
file
"a.python
", line 9, in
do_something
bar = 1/0
zerodivisionerror: integer division or modulo by zero
實際上, 在with語句後面的任何**丟擲異常時, __exit__()方法被執行, 即便不是因為sample類裡的方法產生的異常, 異常發生時, 與之關聯的type, value和trace也會傳給__exit__()方法. 因此丟擲的zerodivisionerror異常被列印出來了. 開發庫時, 清理資源, 關閉檔案等操作都可以放到__exit__()方法中.
因此, python的with語句可以讓**更簡練, 而且處理異常更加簡單.
原文參見
understanding python's "with" statement
Python中with語句的理解
with expr as var block 簡單說明 1,expr可以是任意表示式。2,as var是可選的。3,block是with語句的語句體1,計算expr,並獲取乙個上下文管理器。2,上下文管理器的exit 方法被儲存起來用於之後的呼叫。3,呼叫上下文管理器的enter 方法 4,如果wi...
python難理解的語句解析
1.移除字典點鍵值 key value 對 test dict 輸出原始的字典 print 字典移除前 str test dict 如果key zhihu 則輸出鍵值對字典 new dict 輸出移除後的字典 print 字典移除後 str new dict 字典移除前 字典移除後 2.合併字典 d...
python的語句 Python的語句
python中的兩種語句 1 if條件控制語句 格式 if a int input 請輸入第乙個數 b int input 請輸入第二個數 if a b print a比b小 if else a int input 請輸入第乙個數 b int input 請輸入第二個數 if a b print a...