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

Asyncio返回协程对象而非结果问题咨询(CCXT异步脚本场景)

解决异步脚本返回协程对象而非结果的问题

嘿,我来帮你搞定这个异步编程的小坑!你遇到的问题其实是新手入门异步时最容易踩的误区——没有正确等待协程执行完成,导致拿到的是未运行的协程对象,而不是你想要的交易所价格数据。

核心原因拆解

你提到用了asyncio.gather(),但它本身也是个异步函数(协程),必须用await关键字等待它,才能让事件循环执行所有传入的子协程,并收集它们的返回值。如果直接调用gather()或者只创建了协程对象却没交给事件循环执行,你得到的必然是协程对象列表/协程对象,而非预期的结果。

另外你提到的警告,大概率是因为事件循环的用法过时了(比如用了get_event_loop()+run_until_complete()),Python 3.7+推荐用更简洁安全的asyncio.run()来管理事件循环,能直接避免这类警告。

错误代码示例(你可能踩的坑)

假设你的原代码是类似这样的:

import asyncio
import aiohttp

async def get_exchange_price(exchange):
    # 模拟从交易所API获取价格
    async with aiohttp.ClientSession() as session:
        async with session.get(f"https://api.{exchange}.com/v1/price") as resp:
            return await resp.json()

def main():
    exchanges = ["binance", "coinbase", "kraken"]
    # 这里只创建了协程对象列表,没执行
    coroutines = [get_exchange_price(ex) for ex in exchanges]
    # 调用gather但没await,返回的是gather的协程对象
    results = asyncio.gather(*coroutines)
    print(results)  # 输出类似 <_GatheringFuture pending> 或协程对象列表

if __name__ == "__main__":
    main()

修正后的正确代码

只需要改两个关键地方:

  1. 把main()改成异步函数,在里面await asyncio.gather()
  2. 用asyncio.run()启动主协程,自动管理事件循环
import asyncio
import aiohttp

async def get_exchange_price(exchange):
    async with aiohttp.ClientSession() as session:
        async with session.get(f"https://api.{exchange}.com/v1/price") as resp:
            return await resp.json()

async def main():
    exchanges = ["binance", "coinbase", "kraken"]
    coroutines = [get_exchange_price(ex) for ex in exchanges]
    # 关键:用await等待gather执行完成,拿到结果列表
    results = await asyncio.gather(*coroutines, return_exceptions=True)
    # return_exceptions=True:如果某个协程出错,会返回异常对象而非中断整个任务
    print(results)  # 现在输出实际的价格数据列表

if __name__ == "__main__":
    # Python 3.7+推荐用法,自动创建/关闭事件循环
    asyncio.run(main())

额外提示

  • 永远记住:异步函数调用(比如get_exchange_price(ex))只会创建协程对象,不会立即执行,必须交给事件循环(比如通过await、asyncio.run()或loop.run_until_complete())才能运行。
  • 如果需要处理个别交易所API请求失败的情况,asyncio.gather()的return_exceptions=True参数非常有用,它会把异常作为结果返回,而不是让整个任务崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:25:48