“与...同步”在Python 3.4中 [英] "async with" in Python 3.4

查看:83
本文介绍了“与...同步”在Python 3.4中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

aiohttp入门文档给出了以下客户端示例:

The Getting Started docs for aiohttp give the following client example:

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用户提供以下注释:

And they give the following note for Python 3.4 users:


如果您使用的是Python 3.4,请使用@coroutine装饰器将await替换为from和
异步def。

If you are using Python 3.4, please replace await with yield from and async def with a @coroutine decorator.

如果我按照以下说明进行操作,则会得到:

If I follow these instructions I get:

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不支持异步:

However, this will not run, because async with is not supported in Python 3.4:

$ python3 client.py 
  File "client.py", line 7
    async with session.get(url) as response:
             ^
SyntaxError: invalid syntax

如何翻译 async与语句配合使用Python 3.4吗?

How can I translate the async with statement to work with Python 3.4?

推荐答案

仅不要使用<$的结果c $ c> session.get()作为上下文管理器;直接将其用作协程。 session.get()生成的请求上下文管理器通常会 释放退出时的请求,但使用 response.text() 也是如此,因此您可以在此处忽略它:

Just don't use the result of session.get() as a context manager; use it as a coroutine directly instead. The request context manager that session.get() produces would normally release the request on exit, but so does using response.text(), so you could ignore that here:

@asyncio.coroutine
def fetch(session, url):
    with aiohttp.Timeout(10):
        response = yield from session.get(url)
        return (yield from response.text())

请求返回的包装器没有必需的异步方法( __ aenter __ __ aexit __ ),当不使用Python时,它们会完全省略3.5(请参见相关源代码)。

The request wrapper returned here doesn't have the required asynchronous methods (__aenter__ and __aexit__), they omitted entirely when not using Python 3.5 (see the relevant source code).

如果在 session.get()调用与访问 response.text之间有更多语句(),您可能想使用 try:.. finally:释放连接;如果发生异常,Python 3.5发布上下文管理器还会关闭响应。因为这里需要从response.release()中获得收益,所以不能在Python 3.4之前将其封装在上下文管理器中:

If you have more statements between the session.get() call and accessing the response.text() awaitable, you probably want to use a try:..finally: anyway to release the connection; the Python 3.5 release context manager also closes the response if an exception occurred. Because a yield from response.release() is needed here, this can't be encapsulated in a context manager before Python 3.4:

import sys

@asyncio.coroutine
def fetch(session, url):
    with aiohttp.Timeout(10):
        response = yield from session.get(url)
        try:
            # other statements
            return (yield from response.text())
        finally:
            if sys.exc_info()[0] is not None:
                # on exceptions, close the connection altogether
                response.close()
            else:
                yield from response.release()

这篇关于“与...同步”在Python 3.4中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆