You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

普通同步contextmanager中是否可以使用await异步调用?

能否在上下文管理器中使用await调用

普通同步上下文管理器不支持直接使用await,你遇到的"await" allowed only within async function报错是Python语法的正常约束:

  • 用contextlib.contextmanager装饰器定义的是同步上下文管理器,本质是同步生成器函数,运行在同步执行上下文里
  • 同步上下文管理器配套使用的with关键字块本身也是同步上下文,不允许直接书写await表达式

你给出的测试代码就是典型的错误写法:

from contextlib import contextmanager

@contextmanager
def sample_contextmanager():
    # 仅支持同步调用
    yield
    # 仅支持同步调用

# 错误:同步with块内不允许直接使用await
with sample_contextmanager():
    await some_coroutine()

如果需要在上下文管理器的进入/退出逻辑、以及上下文包裹的代码块中使用await,请使用Python标准库提供的异步上下文管理器实现:

  1. 从contextlib导入asynccontextmanager装饰器,替代同步版本的contextmanager
  2. 定义上下文管理器的函数必须加async关键字声明为异步函数
  3. 调用上下文管理器时必须使用async with关键字,而非同步的with

正确示例代码如下:

from contextlib import asynccontextmanager

@asynccontextmanager
async def sample_async_contextmanager():
    # 进入上下文阶段可以正常写await异步调用
    await async_setup_step()
    yield
    # 退出上下文阶段也可以正常写await异步调用
    await async_teardown_step()

async def run_task():
    # 必须用async with调用异步上下文管理器
    async with sample_async_contextmanager():
        # 块内可以正常执行await异步调用
        await some_coroutine()

注意:同步和异步上下文管理器的装饰器、调用关键字不能混用,否则会触发语法错误或者运行时异常。

内容的提问来源于stack exchange,提问作者Apollos Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:12:25