操作檔案物件時可以:
with open('a.txt') as f:
'**塊'
上述叫做上下文管理協議,即with語句。
想象一下,你有兩個需要結對執行的相關操作,然後,還要在他們中間放置一段**。比如開啟乙個檔案,操作檔案,然後關閉該檔案。
開啟檔案和關閉檔案就是乙個結對的操作。
上下文管理器的常見用例:是資源的加鎖與解鎖,檔案的開啟與關閉。
上下文管理器協議:是指類需要實現 __ enter __ 和 __ exit __ 方法。
就跟迭代器有迭代器協議一樣,迭代器協議需要實現 __ iter __ 和 __ next __ 方法。
上下文管理器,也就是支援上下文管理協議的物件,簡單點講就是,實現了 __ enter __ 和 __ exit __兩個方法的類。這個類也叫做,上下文管理器的類。
寫乙個open類,這個類是乙個上下文管理器:
class open:
def __init__(self, filepath, encoding):
self.filepath = filepath
self.encoding = encoding
def __enter__(self): # 當這個類被with關鍵字執行時,就自動呼叫這個方法。有返回值則呼叫給 as 宣告的變數
print('當這個類被with關鍵字執行時,就自動呼叫這個方法。有返回值則呼叫給 as 宣告的變數')
def __exit__(self, exc_type, exc_val, exc_tb):
print('with 中**塊執行完就執行我這個函式')
with open('1.txt', 'utf-8') as f:
print('with 裡面的**塊')
'''結果:
當這個類被with關鍵字執行時,就自動呼叫這個方法。有返回值則呼叫給 as 宣告的變數
with 裡面的**塊
with 中**塊執行完就執行我這個函式
'''
__ exit __(self, exc_type, exc_val, exc_tb):
裡面的三個引數分別代表:異常型別,異常值,追溯資訊。
注意:with語句中的**塊出現異常後,with後的**都無法執行
基於類的實現:完整實現open方法
乙個上下文管理器的類,起碼要定義 __ enter __ 和 __ exit __ 方法。
class open:
def __init__(self, filepath, method):
self.file = open(filepath, method, encoding='utf-8')
def __enter__(self):
return self.file
def __exit__(self, type, value, traceback):
self.file.close()
with open('1.txt', 'w') as f:
f.write('1111111111')
我們來看看底層發生了什麼?
with語句先暫存了 open 類的 __ exit __ 方法
然後呼叫 open 類的 __ enter __ 方法
__ enter __ 方法開啟檔案並返回給with語句
開啟的檔案控制代碼傳遞給 as 後面的 f 引數
執行with裡面的**塊。
呼叫之前暫存的 __ exit __ 方法
關閉檔案
在第4步和第6步之間,如果發生異常,python會將異常的type,value,traceback傳遞給 __ exit __ 方法。
當異常發生時,with語句會採取哪些步驟?
with把異常的type, value, traceback 傳遞給 __ exit __ 方法
with讓 __ exit __ 處理異常
如果 __ exit __ 返回的是true, 那麼這個異常就被優雅的處理了。
如果 __ exit __ 返回的是true以外的任何東西,那個這個異常將被with 語句丟擲。
當 __ exit __()返回值為true, 那麼異常會被清空,就好像啥都沒發生一樣,with後的語句正常執行.。
class open:
def __init__(self, filepath, mode='r', encoding='utf-8'):
self.filepath = filepath
self.mode = mode
self.encoding = encoding
def __enter__(self):
self.file = open(self.filepath, mode=self.mode, encoding=self.encoding)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type)
self.file.close()
return true
with open('1.txt', 'w', encoding='utf-8') as f:
f.write('哈哈哈')
f.werwer # 丟擲異常,交給exit處理。後面的**正常執行
使用with的語句的目的就是把**塊放入with中執行, with結束後,自動完成清理工作,無需干預。
在需要管理一些資源比如檔案,網路連線和鎖的程式設計環境中,可以在 __ exit __ 中定製自動釋放資源的機制。
contextlib模組:可以使用乙個生成器實現乙個上下文管理器,而不是使用乙個類。眾所周知,在類中還需要實現 __ enter __ 和 __ exit __ 。
from contextlib import contextmanager
@contextmanager
def point(x, y):
print('在yield之前')
yield x * y # yield出去的值賦給 as 後面的變數
print('在yield之後')
with point(3, 4) as p:
print('p',p)
'''結果:
在yield之前
p 12
在yield之後
'''
利用contextlib模組實現乙個open
@contextmanager
def my_open(path):
f = open(path, mode='w')
yield f # 把這個f 賦給as後面的變數
f.close()
with my_open('2.txt') as f:
f.write('我是你爹')
python 上下文管理器
上下文管理器允許你在有需要的時候,精確地分配和釋放資源。使用上下文管理器最廣泛的案例就是with語句了。想象下你有兩個需要結對執行的相關操作,然後還要在它們中間放置一段 上下文管理器就是專門讓你做這種事情的。舉個例子 with open some file w as opened file open...
python上下文管理器
上下文管理器是乙個包裝任意 塊的物件。上下文管理器保證進入上下文管理器時,每次 執行的一致性 當退出上下文管理器時,相關資源會被正確 這裡被正確 指的是在 exit 方法自定義 比如關閉資料庫游標 值得注意的是,上下文管理器一定能夠保證退出步驟的執行。如果進入上下文管理器,根據定義,一定會有退出步驟...
Python 上下文管理器
python中的上下文管理器是乙個包裝任意 塊的物件。它在處理資源的開啟關閉 異常的處理等方面有很好的實現方法。1.上下文管理器的語法 假設我們需要讀取乙個檔案中的資料,如下 try test file open test.txt r contents test file.read finally ...