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

为何Python同步与异步代码执行同一逻辑返回不同类型?

问题原因与解决方法

核心差异:asyncio.gather()的返回特性

同步代码中,get_response()直接返回单个字典对象,所以type(json_response)是dict。

而异步代码里你用了asyncio.gather(get_response(user_url)),这个函数的设计逻辑是:接收一个或多个可等待对象,并发执行后返回所有结果组成的列表——哪怕只传入一个协程,它也会把结果包装成单元素列表返回,所以type(json_response)是list。

修正方案

方案1:直接await单个协程(推荐,适合单任务场景)

不需要用gather,直接await单个协程即可:

import urllib.request
import json
import asyncio

async def get_response(user_url):
    resp = urllib.request.urlopen(user_url).read()
    resp_json = json.loads(resp)
    return resp_json['results'][0]


async def make_request(user_url):
    json_response = await get_response(user_url)  # 直接await单个协程
    print(type(json_response))  # 输出 <class 'dict'>

USER_URL = 'https://randomuser.me/api'
asyncio.run(make_request(USER_URL))

方案2:若需保留gather,取列表第一个元素

如果是为了后续扩展多任务而保留gather,可以直接提取列表的第一个元素:

import urllib.request
import json
import asyncio

async def get_response(user_url):
    resp = urllib.request.urlopen(user_url).read()
    resp_json = json.loads(resp)
    return resp_json['results'][0]


async def make_request(user_url):
    json_response = (await asyncio.gather(get_response(user_url)))[0]  # 取列表第一个元素
    print(type(json_response))  # 输出 <class 'dict'>

USER_URL = 'https://randomuser.me/api'
asyncio.run(make_request(USER_URL))

补充说明

asyncio.gather()的核心用途是并发执行多个异步任务,比如同时请求多个URL时:

results = await asyncio.gather(
    get_response(url1),
    get_response(url2),
    get_response(url3)
)
# results 是包含三个字典的列表

单任务场景下完全没必要使用它,直接await单个协程更简洁。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:11:09