Python上下文管理協議:__enter__和__exit__
阿新 • • 發佈:2018-12-17
上下文管理器(context manager)是Python2.5開始支援的一種語法,用於規定某個物件的使用範圍。一旦進入或者離開該使用範圍,會有特殊操作被呼叫 (比如為物件分配或者釋放記憶體)。它的語法形式是with...as...
所謂上下文管理協議,就是咱們開啟檔案時常用的一種方法:with
__enter__(self):當with開始執行的時候觸發此方法的執行
__exit__(self, exc_type, exc_val, exc_tb):當with執行結束之後觸發此方法的執行
exc_type如果丟擲異常,這裡獲取異常的型別
exc_val如果丟擲異常,這裡顯示異常內容
exc_tb如果丟擲異常,這裡顯示所在位置
程式碼示例:
1 class Sample: 2 def __enter__(self): 3 print "In __enter__()" 4 return "Foo" 5 6 def __exit__(self, type, value, trace): 7 print "In __exit__()" 8 9 def get_sample(): 10 return Sample() 11 12 with get_sample() as sample: 13 print"sample:", sample
輸出如下:
1 In __enter__() 2 sample: Foo 3 In __exit__()
__enter__()
方法被執行
__enter__()
方法返回的值 - 這個例子中是”Foo”,賦值給變數’sample’
執行程式碼塊,列印變數”sample”的值為 “Foo”
__exit__()
方法被呼叫
改一下程式碼,看看具體如何工作的:
1 class Sample: 2 def __enter__(self): 3 return self 4 def __exit__(self, type, value, trace): 5 print "type:", type 6 print "value:", value 7 print "trace:", trace 8 9 def do_something(self): 10 bar = 1/0 11 return bar + 10 12 13 with Sample() as sample: 14 sample.do_something()
程式碼執行後:
1 type: <type 'exceptions.ZeroDivisionError'> 2 value: integer division or modulo by zero 3 trace: <traceback object at 0x1004a8128> 4 Traceback (most recent call last): 5 File "./with_example02.py", line 19, in <module> 6 sample.do_somet hing() 7 File "./with_example02.py", line 15, in do_something 8 bar = 1/0 9 ZeroDivisionError: integer division or modulo by zero
開發庫時,清理資源,關閉檔案等等操作,都可以放在__exit__
方法當中。因此,Python的with語句是提供一個有效的機制,讓程式碼更簡練,同時在異常產生時,清理工作更簡單。