最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python?中的異步上下文生成器?@asynccontextmanager詳解

 更新時間:2026年02月07日 09:36:29   作者:serve?the?people  
@asynccontextmanager是Python?contextlib模塊提供的異步上下文管理器裝飾器,專為異步編程設(shè)計,本文給大家介紹Python中的異步上下文生成器?@asynccontextmanager的相關(guān)操作,感興趣的朋友跟隨小編一起看看吧

Python 中的 @asynccontextmanager 裝飾器,它是異步編程中用于快速定義異步上下文管理器的工具,基于 contextlib 模塊實現(xiàn),核心作用是讓你用異步生成器(async yield) 替代手動定義異步上下文管理器的兩個魔法方法,大幅簡化代碼。

先鋪墊:異步上下文管理器的基礎(chǔ)

在異步代碼中,我們會用 async with 語句管理資源(比如異步連接數(shù)據(jù)庫、異步打開文件、異步網(wǎng)絡(luò)會話),而能被 async with 使用的對象,就是異步上下文管理器。

手動定義一個異步上下文管理器,需要實現(xiàn)兩個異步魔法方法:

  1. __aenter__():進入 async with 時執(zhí)行,返回要操作的資源(比如數(shù)據(jù)庫連接);
  2. __aexit__():退出 async with 時執(zhí)行,負責釋放資源(比如關(guān)閉連接、處理異常)。

手動實現(xiàn)的缺點是代碼繁瑣,而 @asynccontextmanager 就是為了解決這個問題而生的。

@asynccontextmanager 核心作用

通過這個裝飾器,你可以用一個異步生成器函數(shù),直接定義出異步上下文管理器的「進入邏輯」和「退出邏輯」,無需手動實現(xiàn) __aenter____aexit__

  • 生成器中 yield 之前的代碼 → 對應(yīng) __aenter__() 的邏輯(進入上下文,初始化/獲取資源);
  • 生成器中 yield 之后的代碼 → 對應(yīng) __aexit__() 的邏輯(退出上下文,釋放/清理資源);
  • yield 后面的值 → 就是 async with ... as 變量 中「變量」接收到的資源對象。

基本使用語法

from contextlib import asynccontextmanager
import asyncio
# 用@asynccontextmanager裝飾異步生成器函數(shù)
@asynccontextmanager
async def 異步上下文管理器名(參數(shù)):
    # 1. 進入邏輯:初始化/獲取異步資源(對應(yīng)__aenter__)
    資源 = 等待異步操作獲取資源()
    try:
        yield 資源  # 把資源返回給async with ... as 變量,暫停執(zhí)行
    finally:
        # 2. 退出邏輯:釋放/清理資源(對應(yīng)__aexit__,無論是否異常都會執(zhí)行)
        等待異步操作釋放資源(資源)
# 調(diào)用:用async with語句
async def main():
    async with 異步上下文管理器名(參數(shù)) as 資源變量:
        # 操作資源
        await 資源變量.異步方法()
# 運行異步主函數(shù)
asyncio.run(main())

? 關(guān)鍵:必須用 try...finally 包裹 yield,確保即使上下文內(nèi)代碼拋出異常,資源清理邏輯也能執(zhí)行。

實際示例:異步文件管理器

@asynccontextmanager 實現(xiàn)一個簡單的異步文件操作上下文管理器(模擬異步文件IO,實際Python3.7+有原生asyncio.open):

from contextlib import asynccontextmanager
import asyncio
# 定義異步上下文管理器:異步打開/關(guān)閉文件
@asynccontextmanager
async def async_open(file_path, mode="r"):
    print("進入上下文:異步打開文件")
    # 模擬異步打開文件(實際是同步,僅作演示)
    file = open(file_path, mode, encoding="utf-8")
    try:
        yield file  # 返回文件對象,供async with使用
    finally:
        print("退出上下文:異步關(guān)閉文件")
        file.close()  # 清理資源:關(guān)閉文件
# 調(diào)用異步上下文管理器
async def read_file():
    async with async_open("test.txt", "w") as f:
        await asyncio.sleep(0.1)  # 模擬異步寫操作
        f.write("Hello @asynccontextmanager!")
    print("文件操作完成,資源已釋放")
# 運行異步代碼
asyncio.run(read_file())

執(zhí)行結(jié)果

進入上下文:異步打開文件
退出上下文:異步關(guān)閉文件
文件操作完成,資源已釋放

可以看到:進入async with時執(zhí)行yield前的代碼,退出時執(zhí)行yield后的清理代碼。

進階示例:異步數(shù)據(jù)庫連接(模擬)

實際開發(fā)中,@asynccontextmanager 最常用在異步數(shù)據(jù)庫、異步Redis、異步網(wǎng)絡(luò)請求等場景,比如模擬異步MySQL連接:

from contextlib import asynccontextmanager
import asyncio
# 模擬異步數(shù)據(jù)庫客戶端
class AsyncMySQLClient:
    async def connect(self):
        print("建立異步數(shù)據(jù)庫連接")
        return self
    async def close(self):
        print("關(guān)閉異步數(shù)據(jù)庫連接")
    async def query(self, sql):
        print(f"執(zhí)行異步SQL:{sql}")
        return [{"id": 1, "name": "test"}]
# 定義異步數(shù)據(jù)庫連接的上下文管理器
@asynccontextmanager
async def get_mysql_conn():
    # 1. 進入邏輯:建立異步連接
    client = AsyncMySQLClient()
    conn = await client.connect()
    try:
        yield conn  # 返回連接對象,供業(yè)務(wù)代碼使用
    finally:
        # 2. 退出邏輯:關(guān)閉連接,釋放資源
        await conn.close()
# 業(yè)務(wù)代碼:使用數(shù)據(jù)庫連接
async def query_data():
    async with get_mysql_conn() as conn:
        result = await conn.query("SELECT * FROM user")
        print(f"查詢結(jié)果:{result}")
# 運行
asyncio.run(query_data())

執(zhí)行結(jié)果

建立異步數(shù)據(jù)庫連接
執(zhí)行異步SQL:SELECT * FROM user
查詢結(jié)果:[{'id': 1, 'name': 'test'}]
關(guān)閉異步數(shù)據(jù)庫連接

無論query中是否拋出異常,close都會執(zhí)行,確保數(shù)據(jù)庫連接被釋放。

關(guān)鍵注意點

  1. 裝飾的必須是異步生成器:函數(shù)必須加 async def,且內(nèi)部有 yield(普通生成器不行,普通生成器用@contextmanager);
  2. 異常處理:yield 處可能拋出上下文內(nèi)的異常,必須用try...finally,否則異常會跳過清理邏輯;
  3. 與同步版的區(qū)別:同步上下文管理器用 @contextmanager(裝飾普通生成器),異步用 @asynccontextmanager(裝飾異步生成器),前者配合with,后者配合async with;
  4. 返回值yield 資源 是可選的,如果上下文不需要返回資源,直接yield即可(async with 管理器: 不帶as)。

對比:手動實現(xiàn) vs @asynccontextmanager

手動實現(xiàn)異步上下文管理器的方式重寫上面的「異步文件管理器」,對比代碼量:

import asyncio
# 手動實現(xiàn)異步上下文管理器(需實現(xiàn)__aenter__/__aexit__)
class AsyncOpen:
    def __init__(self, file_path, mode="r"):
        self.file_path = file_path
        self.mode = mode
        self.file = None
    # 異步進入方法
    async def __aenter__(self):
        print("進入上下文:異步打開文件")
        self.file = open(self.file_path, self.mode, encoding="utf-8")
        return self.file
    # 異步退出方法(exc_type/val/tb 接收異常信息)
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        print("退出上下文:異步關(guān)閉文件")
        if self.file:
            self.file.close()
# 調(diào)用方式不變
async def read_file():
    async with AsyncOpen("test.txt", "w") as f:
        f.write("手動實現(xiàn)異步上下文管理器")
asyncio.run(read_file())

可以明顯看到:手動實現(xiàn)需要寫大量模板代碼,而@asynccontextmanager用一個異步生成器就搞定,代碼簡潔數(shù)倍。

總結(jié)

  1. @asynccontextmanager 是 Python contextlib 模塊提供的異步上下文管理器裝飾器,專為異步編程設(shè)計;
  2. 核心是將異步生成器函數(shù)轉(zhuǎn)為異步上下文管理器,yield 前是「進入邏輯」,yield 后是「退出清理邏輯」;
  3. 必須配合 async with 使用,且生成器內(nèi)要加 try...finally 保證資源必被清理;
  4. 對比手動實現(xiàn) __aenter__/__aexit__,大幅簡化異步資源管理的代碼,是異步開發(fā)中管理臨時資源(連接、文件、會話)的最佳實踐之一;
  5. 同步場景用它的兄弟裝飾器 @contextmanager(配合with,裝飾普通生成器),異步場景用@asynccontextmanager(配合async with,裝飾異步生成器)。

到此這篇關(guān)于Python 中的異步上下文生成器 @asynccontextmanager的文章就介紹到這了,更多相關(guān)Python 異步上下文生成器 @asynccontextmanager內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python進階篇之正則表達式常用語法總結(jié)

    Python進階篇之正則表達式常用語法總結(jié)

    正則表達式是一個特殊的字符序列,它能幫助你方便的檢查一個字符串是否與某種模式匹配。本文為大家總結(jié)了一些正則表達式常用語法,希望有所幫助
    2022-08-08
  • 解決reload(sys)后print失效的問題

    解決reload(sys)后print失效的問題

    這篇文章主要介紹了解決reload(sys)后print失效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python使用Pydantic進行數(shù)據(jù)驗證與序列化詳解

    Python使用Pydantic進行數(shù)據(jù)驗證與序列化詳解

    Pydantic庫通過使用Python類型注解來提供數(shù)據(jù)驗證和設(shè)置管理,使得數(shù)據(jù)處理變得更加可靠和高效,本文將深入探討Pydantic的使用,通過理論講解和實際代碼示例,展示如何在項目中高效利用Pydantic進行數(shù)據(jù)驗證與序列化,需要的可以了解下
    2025-12-12
  • Python實現(xiàn)大文件排序的方法

    Python實現(xiàn)大文件排序的方法

    這篇文章主要介紹了Python大文件排序的方法,涉及Python針對文件、緩存及日期等操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • 系統(tǒng)解析Python模擬Windows文件名排序的三種實現(xiàn)方案

    系統(tǒng)解析Python模擬Windows文件名排序的三種實現(xiàn)方案

    在文件管理場景中,Windows資源管理器的排序規(guī)則因其符合人類自然認知而備受青睞,本文將系統(tǒng)解析Windows排序規(guī)則并提供三種Python實現(xiàn)方案,大家可以根據(jù)需要進行選擇
    2026-03-03
  • python五子棋游戲的設(shè)計與實現(xiàn)

    python五子棋游戲的設(shè)計與實現(xiàn)

    這篇文章主要為大家詳細介紹了python五子棋游戲的設(shè)計與實現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Python3.7 + Yolo3實現(xiàn)識別語音播報功能

    Python3.7 + Yolo3實現(xiàn)識別語音播報功能

    這篇文章主要介紹了Python3.7 + Yolo3識別語音播報功能,開始之前我們先得解析出來Yolo3的代碼,從而獲取到被識別出來的物體標簽,具體詳細過程跟隨小編一起看看吧
    2021-12-12
  • 解決Python Matplotlib繪圖數(shù)據(jù)點位置錯亂問題

    解決Python Matplotlib繪圖數(shù)據(jù)點位置錯亂問題

    這篇文章主要介紹了解決Python Matplotlib繪圖數(shù)據(jù)點位置錯亂問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • python面向?qū)ο蟀鎸W(xué)生信息管理系統(tǒng)

    python面向?qū)ο蟀鎸W(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細介紹了python面向?qū)ο蟀鎸W(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • PyCharm永久激活方式(推薦)

    PyCharm永久激活方式(推薦)

    這篇文章主要介紹了PyCharm永久激活方式,本文通過圖文并茂的方式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03

最新評論

石城县| 禹城市| 安仁县| 大洼县| 舞钢市| 沂水县| 宁津县| 五寨县| 基隆市| 怀柔区| 方山县| 东乡| 齐齐哈尔市| 祁东县| 山东省| 武汉市| 湖北省| 墨竹工卡县| 南京市| 威信县| 大冶市| 连云港市| 宁波市| 铜梁县| 肥西县| 乌兰察布市| 额济纳旗| 鄂伦春自治旗| 葫芦岛市| 清苑县| 婺源县| 横山县| 盐津县| 鄢陵县| 沐川县| 福海县| 汽车| 乐昌市| 开远市| 江门市| 长顺县|