1. 程式人生 > >Python上下文管理協議:__enter__和__exit__

Python上下文管理協議:__enter__和__exit__

上下文管理器(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語句是提供一個有效的機制,讓程式碼更簡練,同時在異常產生時,清理工作更簡單。