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

Python异步代码运行.py文件报await only allowed in async function错误

报错根因

这个报错和自定义read_blob()方法是否标记async无关,触发错误的是脚本最后一行全局作用域里的await调用:

  • 原生Python语法明确规定:await关键字仅允许在被async标记的函数/方法内部使用,模块顶层的全局作用域不属于async函数范围,直接写await就会抛出该错误。
  • Jupyter Notebook的IPython内核做了特殊兼容,会自动给每个单元格的代码包裹异步运行上下文,所以顶层直接写await可以正常运行,但这不是Python原生支持的写法,放到普通.py文件里执行就会报错。
  • 原代码还存在一个隐含问题:使用了pd.read_parquet但没有导入pandas库,修复语法报错后运行也会触发NameError。
修复方案

写正式.py脚本时,需要把顶层的异步逻辑封装到async入口函数里,通过asyncio.run()启动事件循环执行,同时补全缺失的导入、用完异步客户端后主动释放连接:

# 补全缺失的pandas导入
import pandas as pd
from azure.storage.blob.aio import ContainerClient
import asyncio
from azure.core.exceptions import ResourceNotFoundError
from io import BytesIO


class AsyncContainerClient(ContainerClient):
    async def read_blob(self,
                  blob_name: str,
                  add_blob_name_col=False,
                  add_blob_date_col=False,
                  preprocessing_func=None,
                  zip_regex=r'.+\.gz$',
                  csv_regex='.+\.csv(\.gz)?$',
                  parquet_regex='.+\.parquet$',
                  regex_string=None,
                  **kwargs):
        assert isinstance(blob_name, str), f'{blob_name} is not a string'

        try:
            blob = await self.download_blob(blob_name)
            with BytesIO() as byte_stream:
                await blob.readinto(byte_stream)
                byte_stream.seek(0)
                return pd.read_parquet(byte_stream, engine='pyarrow')
        except ResourceNotFoundError:
            return 0


async def main():
    blob_sas_url = "https://proan.blob"
    acc = AsyncContainerClient.from_container_url(blob_sas_url)
    test_dirs = ["models1/model.parquet", "models2/model.parquet", "models3/model.parquet"]
    res = await asyncio.gather(*(acc.read_blob(f) for f in test_dirs))
    # 此处添加res的后续处理逻辑
    print(res)
    # 用完异步客户端主动关闭,释放连接资源
    await acc.close()

if __name__ == "__main__":
    asyncio.run(main())
补充说明

如果是在Python 3.8+的原生交互式命令行环境中,可以执行python -m asyncio启动支持顶层await的交互模式,该模式下可以直接在全局作用域写await,但该方式仅适用于交互式调试场景,正式脚本仍需使用上述asyncio.run()的入口写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:21:23