Python 進(jìn)階: 上下文管理器
在Python中,上下文管理器(Context Manager)是一種用于管理資源(如文件、網(wǎng)絡(luò)連接、鎖等)的對(duì)象,它確保在使用完資源后能夠正確釋放或清理資源。

上下文管理器通常與with語(yǔ)句一起使用。一個(gè)著名的例子是 with open() 語(yǔ)句:
with open('notes.txt', 'w') as f:
    f.write('some todo...')這將打開(kāi)一個(gè)文件,并確保在程序執(zhí)行離開(kāi) with 語(yǔ)句的上下文之后自動(dòng)將其關(guān)閉。
它還處理異常,并確保即使在發(fā)生異常的情況下也能正確關(guān)閉文件。 在內(nèi)部,上面的代碼翻譯成這樣的東西:
f = open('notes.txt', 'w')
try:
    f.write('some todo...')
finally:
    f.close()應(yīng)用場(chǎng)景
- 成對(duì)操作:打開(kāi)/關(guān)閉、獲取/釋放、開(kāi)始/結(jié)束
 - 資源清理:需要確保資源釋放(即使發(fā)生異常)
 - 狀態(tài)切換:需要臨時(shí)修改全局狀態(tài)后恢復(fù)
 - 異常處理:需要統(tǒng)一處理特定錯(cuò)誤
 - 性能監(jiān)控:需要精確測(cè)量代碼塊執(zhí)行時(shí)間
 
自定義上下文管理器
- __enter__():進(jìn)入上下文時(shí)調(diào)用,返回資源對(duì)象
 - __exit__():退出上下文時(shí)調(diào)用,處理異常和清理
 
class ManagedFile:
    def __init__(self, filename):
        print('init', filename)
        self.filename = filename
    def __enter__(self):
        print('enter')
        self.file = open(self.filename, 'w')
        return self.file
    def __exit__(self, exc_type, exc_value, exc_traceback):
        if self.file:
            self.file.close()
        print('exit')
with ManagedFile('notes.txt') as f:
    print('doing stuff...')
    f.write('some todo...')contextlib 裝飾器
除了編寫(xiě)類,我們還可以編寫(xiě)一個(gè)生成器函數(shù),并使用 contextlib.contextmanager 裝飾器對(duì)其進(jìn)行裝飾。 然后,我們也可以使用 with 語(yǔ)句調(diào)用該函數(shù)。
對(duì)于這種方法,函數(shù)必須在 try 語(yǔ)句中 yield 資源,并且釋放資源的 __exit__ 方法的所有內(nèi)容現(xiàn)在都在相應(yīng)的 finally 語(yǔ)句內(nèi)。
from contextlib import contextmanager
@contextmanager
def file_manager(filename, mode):
    file = open(filename, mode)  # 相當(dāng)于 __enter__
    try:
        yield file  # 返回資源對(duì)象
    finally:
        file.close()  # 相當(dāng)于 __exit__
# 使用示例
with file_manager("test.txt", "w") as f:
    f.write("Hello Context Manager!")高級(jí)功能
(1) 異常處理
在 __exit__() 中可通過(guò)參數(shù)獲取異常信息:
- exc_type:異常類型
 - exc_val:異常值
 - exc_tb:異常堆棧
 
def __exit__(self, exc_type, exc_val, exc_tb):
    if exc_type:
        print(f"Exception handled: {exc_val}")
    self.cleanup()
    return True  # 返回 True 表示異常已被處理(2) 嵌套上下文管理器
with open("file1.txt") as f1, open("file2.txt") as f2:
    data1 = f1.read()
    data2 = f2.read()
    # 自動(dòng)關(guān)閉兩個(gè)文件(3) 異步上下文管理器
class AsyncConnection:
    async def __aenter__(self):
        await self.connect()
        return self
    
    async def __aexit__(self, exc_type, exc, tb):
        await self.close()
# 使用
async with AsyncConnection() as conn:
    await conn.send_data()上下文管理器通過(guò)封裝資源管理邏輯,顯著提升代碼的可讀性和健壯性。掌握其自定義方法和高級(jí)特性,能讓你編寫(xiě)更優(yōu)雅、安全的 Python 代碼。















 
 
 
















 
 
 
 