上下文管理器
阿新 • • 發佈:2018-07-17
總結 yield 實現 管理器 nag The eat span 使用
任何實現了 __enter__() 和 __exit__() 方法的對象都可稱之為上下文管理器,上下文管理器對象可以使用 with 關鍵字。顯然,文件(file)對象也實現了上下文管理器。
那麽文件對象是如何實現這兩個方法的呢?我們可以模擬實現一個自己的文件類,讓該類實現 __enter__() 和 __exit__() 方法。
class File():
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
print("entering")
self.f = open(self.filename, self.mode)
return self.f
def __exit__(self, *args):
print("will exit")
self.f.close()
__enter__() 方法返回資源對象,這裏就是你將要打開的那個文件對象,__exit__() 方法處理一些清除工作。
因為 File 類實現了上下文管理器,現在就可以使用 with 語句了。
with File(‘out.txt‘, ‘w‘) as f:
print("writing")
f.write(‘hello, python‘)
這樣,你就無需顯示地調用 close 方法了,由系統自動去調用,哪怕中間遇到異常 close 方法也會被調用。
實現上下文管理器的另外方式
Python 還提供了一個 contextmanager 的裝飾器,更進一步簡化了上下文管理器的實現方式。通過 yield 將函數分割成兩部分,yield 之前的語句在 __enter__ 方法中執行,yield 之後的語句在 __exit__ 方法中執行。緊跟在 yield 後面的值是函數的返回值。
from contextlib import contextmanager
@contextmanager
def my_open(path, mode):
f = open(path, mode)
yield f
f.close()
調用
with my_open(‘out.txt‘, ‘w‘) as f:
f.write("hello , the simplest context manager"
總結
Python 提供了 with 語法用於簡化資源操作的後續清除操作,是 try/finally 的替代方法,實現原理建立在上下文管理器之上。此外,Python 還提供了一個 contextmanager 裝飾器,更進一步簡化上下管理器的實現方式。
上下文管理器