Python中的上下文管理器

2022-06-20 20:00:08 字數 3489 閱讀 9899

操作檔案物件時可以:

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 ...