在 Python3.5 asyncio 中等待后无法访问 Http 请求数据

Unable to access Http request data after await in Python3.5 asyncio

我一直在尝试使用 Python3.5 aiohttp 并编写了这个简单的包装函数 -

 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() return 是一个协程。 访问像 res.status 这样的属性效果很好,但是 text()json() return 是一个我无法从中检索实际响应的协程。

我想我可能没有完全理解某些东西,但我认为等待未来应该 return 准备就绪时的实际价值。

我哪里错了?

我不确定我是否理解你的问题,但你是在寻找 asyncio.run 吗?

>>> async def f():
...     return 1
...
>>> print(f())
<coroutine object f at 0x000002CEE50AC5C0>
>>> print(asyncio.run(f()))
1

你是对的,你在等待你创造的request的未来。但是当这个 future 完成并且你得到你的回复时,还不清楚回复的每个内容是否可用。

因此,访问某些响应负载本身是您必须等待的未来。

您可以在 aiohttp.ClientResponse documentation 中看到:

coroutine json(*, encoding=None, loads=json.loads, content_type='application/json')

使用指定的编码和加载程序将响应的主体读取为 JSON、return dict。如果数据仍然不可用,将完成读取调用 (...)

这应该会如您所愿地工作:

 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 await response.json()
        async with session.post(url, data=data, headers=headers) as response:
            return await response.json()