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

Python asyncio学习:解决'coroutine was never awaited'警告问题

解决asyncio中'coroutine was never awaited'运行时警告

嘿,咱们来一步步搞定这个问题!我先帮你分析警告产生的原因,再给出对应的修复方案。

警告原因分析

你遇到的'coroutine was never awaited'警告,核心问题出在异步函数的调用方式上:

  • 当你直接调用faire_toutes_les_requetes_sans_bloquer()时,Python只会返回一个协程对象,并不会自动调度它执行。这个协程如果没被await或者通过事件循环触发,就会一直处于挂起状态,于是抛出警告。
  • 另外你的代码里还有两个小问题:
    1. 手动获取和管理事件循环(get_event_loop()、run_until_complete()、close())的写法在Python 3.7+已经不推荐了,现在有更简洁的方式。
    2. requete_sans_bloquer里的uid = (await response.json()['uuid'])写法错误——response.json()本身是个协程,你得先await拿到完整的json结果,再提取uuid,否则会直接报错。

修复方案&修改后的代码

针对这些问题,我们做三处关键修改:

修改点说明

  • 用asyncio.run()触发顶层协程的执行,替代直接调用异步函数,这是Python 3.7+推荐的异步入口写法。
  • 移除手动管理事件循环的代码,asyncio.run()会自动创建、运行和关闭事件循环,无需手动操作。
  • 修正response.json()的await位置,确保先拿到解析后的json数据再提取字段。

完整修复代码

import time
import datetime
import random
import asyncio
import aiohttp
import requests

def requete_bloquante(num):
    print(f'Get {num}')
    uid = requests.get("https://httpbin.org/uuid").json()['uuid']
    print(f"Res {num}: {uid}")

def faire_toutes_les_requetes():
    for x in range(10):
        requete_bloquante(x)

print("Bloquant : ")
start = datetime.datetime.now()
faire_toutes_les_requetes()
exec_time = (datetime.datetime.now() - start).seconds
print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")

async def requete_sans_bloquer(num, session):
    print(f'Get {num}')
    async with session.get("https://httpbin.org/uuid") as response:
        # 先await解析json,再提取uuid
        response_data = await response.json()
        uid = response_data['uuid']
        print(f"Res {num}: {uid}")

async def faire_toutes_les_requetes_sans_bloquer():
    async with aiohttp.ClientSession() as session:
        # 创建所有协程任务
        tasks = [requete_sans_bloquer(x, session) for x in range(10)]
        # 等待所有任务完成
        await asyncio.gather(*tasks)
    print("Fin de la boucle !")

print("Non bloquant : ")
start = datetime.datetime.now()
# 用asyncio.run运行顶层协程,触发执行
asyncio.run(faire_toutes_les_requetes_sans_bloquer())
exec_time = (datetime.datetime.now() - start).seconds
print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")

运行修改后的代码,你会发现警告消失了,异步请求也能正常执行,而且耗时会比同步版本短很多——这才是asyncio该有的效果!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:17:59