aiohttp的入门文档提供了以下客户端示例:
import asyncio
import aiohttp
async def fetch_page(session, url):
with aiohttp.Timeout(10):
async with session.get(url) as response:
assert response.status == 200
return await response.read()
loop = asyncio.get_event_loop()
with aiohttp.ClientSession(loop=loop) as session:
content = loop.run_until_complete(
fetch_page(session, 'http://python.org'))
print(content)
他们为Python 3.4用户提供以下注释:
如果您使用的是Python 3.4,请使用@coroutine装饰器替换等于yield和async def .
如果我遵循这些说明,我会得到:
import aiohttp
import asyncio
@asyncio.coroutine
def fetch(session, url):
with aiohttp.Timeout(10):
async with session.get(url) as response:
return (yield from response.text())
if __name__ == '__main__':
loop = asyncio.get_event_loop()
with aiohttp.ClientSession(loop=loop) as session:
html = loop.run_until_complete(
fetch(session, 'http://python.org'))
print(html)
但是,这不会运行,因为Python 3.4不支持 async with
:
$ python3 client.py
File "client.py", line 7
async with session.get(url) as response:
^
SyntaxError: invalid syntax
如何将 async with
语句翻译为与Python 3.4一起使用?
2 回答
aiohttp
的examples使用3.4语法实现 . 基于json client example,您的功能将是:Upd:
请注意,Martijn的解决方案适用于简单的情况,但在特定情况下可能会导致不必要的行为:
除了例外你'll get also warning 2440837 . This may lead to connections leak in complex app. You will avoid this problem if you' ll手动调用
resp.release()
/resp.close()
:我认为最好遵循官方示例(和
__aexit__
implementation)并明确地调用resp.release()
/resp.close()
.只是不要使用
session.get()
的结果作为上下文管理器;直接用它作为协程 .session.get()
生成的请求上下文管理器通常在退出时release the request,但是so does using response.text(),所以你可以在这里忽略它:这里返回的请求包装器没有必需的异步方法(
__aenter__
和__aexit__
),它们在不使用Python 3.5时完全省略(参见relevant source code) .如果
session.get()
调用和访问response.text()
之间有更多的语句,你可能想要使用try:..finally:
来释放连接;如果发生异常,Python 3.5发行版上下文管理器也会关闭响应 . 因为这里需要yield from response.release()
,所以在Python 3.4之前不能将它封装在上下文管理器中: