詳解python中的with關鍵字
阿新 • • 發佈:2019-02-09
對於系統資源如檔案、資料庫連線、socket 而言,應用程式開啟這些資源並執行完業務邏輯之後,必須做的一件事就是要關閉(斷開)該資源。
如何正確的關閉一個檔案呢?
1.普通版
def test0():
f = open("1.txt", "w")
f.write("0000")
f.close()
2.進階版
def test1():
f = open("1.txt", "w")
try:
f.write("111111")
except Exception:
print("ERROR")
finally :
f.close()
3.高階版
def test2():
with open("1.txt", "w") as f:
f.write("2222")
使用with關鍵字的方法更為簡潔,它的實現原理是什麼,這就涉及到上下文管理器。
任何實現了 __enter__()
和 __exit__()
方法的物件都可稱之為上下文管理器
4.用類還原with的實現原理
class Test4(object):
def __init__(self, file_name, mode):
self.file_name = file_name
self.mode = mode
def __enter__(self):
self.f = open(self.file_name, self.mode)
return self.f
def __exit__(self,*args):
self.f.close()
with Test4("1.txt", "w") as f:
f.write("4444")
"""
首先Test4("1.txt", "w")初始化例項物件,
然後with會尋找類中是否有__enter__ 和 __exit__,
如果有則呼叫__enter__函式,
最後__enter__() 方法返回資源物件,這裡就是你將要開啟
的那個檔案物件,__exit__() 方法處理一些清除工作。
"""
5.使用contextmanager裝飾器,實現with功能
from contextlib import contextmanager
"""
Python 還提供了一個 contextmanager 的裝飾器,更進一步簡化
了上下文管理器的實現方式。通過 yield 將函式分割成兩部分,yield 之前的
語句在 __enter__ 方法中執行,yield 之後的語句在 __exit__ 方法中執行。
緊跟在 yield 後面的值是函式的返回值。
"""
@contextmanager
def test5(path, mode):
f = open(path, mode)
yield f
f.close()
with test5('out.txt', 'w') as f:
f.write("5555")
總結:
Python 提供了 with 語法用於簡化資源操作的後續清除操作,是 try/finally 的替代方法,實現原理建立在上下文管理器之上。此外,Python 還提供了一個 contextmanager 裝飾器,更進一步簡化上下管理器的實現方式。