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

Python3.5 asyncio中await后无法获取HTTP请求数据问题

为什么aiohttp响应的json()/text()返回协程而非实际内容?

我尝试用Python 3.5的aiohttp库写了一个简单的异步HTTP请求包装函数:

async def perform_async_http(self, url, method, data='', headers={}):
    async with aiohttp.ClientSession() as session:
        if method.lower() == 'get':
            async with session.get(url, headers=headers) as response:
                return response
        async with session.post(url, data=data, headers=headers) as response:
            return response

之后我用这个函数写了下面的代码:

http_future = self.perform_async_http(url, "post", data, headers)
res = await http_future
print(res.json())

问题是res.json()或者res.text()返回的是一个协程,没办法拿到实际的响应内容;但访问res.status这类属性却能正常工作。我原本以为await http_future会在就绪时返回实际值,想请教下我哪里理解错了?


问题解析与解决方法

其实你这里的误解点很清晰:你通过await http_future确实拿到了真实的aiohttp.ClientResponse对象——这就是为什么res.status这类属性能直接访问,因为它们是响应对象的同步属性,不需要IO操作就能获取。

但json()、text()、read()这些方法不一样,它们需要从网络流中读取完整的响应体内容,这个过程是异步IO操作,所以aiohttp把它们设计成了协程函数。也就是说,调用这些方法只会返回一个协程对象,你必须再用await去等待它执行完成,才能拿到实际的响应内容。

修正后的代码应该是这样:

http_future = self.perform_async_http(url, "post", data, headers)
res = await http_future
# 给json()加上await,等待响应体读取完成
response_content = await res.json()
print(response_content)

另外给你提个小细节优化:你的函数里headers={}作为默认参数是有坑的——Python中默认参数是在函数定义时创建的,多次调用函数会复用同一个字典实例,可能导致意外的头部参数污染。建议改成下面的写法:

async def perform_async_http(self, url, method, data='', headers=None):
    # 如果没传headers,就初始化一个新字典
    headers = headers or {}
    async with aiohttp.ClientSession() as session:
        if method.lower() == 'get':
            async with session.get(url, headers=headers) as response:
                return response
        async with session.post(url, data=data, headers=headers) as response:
            return response

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:52:41