Python 异步编程 async / await

async ioloop await 2017年06月15日 星期四

随着PY2时代的退去,势必需要研究一番PY3,最重要的改动就是协程异步编程相关,编程道路上的几个历程,多进程编程,多线程编程,协程编程即异步编程。

在这里推荐一篇文章:https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/,这里面很详细介绍了关于 async / await 相关的知识。

Tornado 框架目前的版本已经支持了这样语法,如:

class DemoHandler(tornado.web.RequestHandler):
    
    # @tornado.gen.coroutine
    async def get(self, *args, **kwargs):
        c = await self.to_do()
        self.write("hello word" + c)

    async def to_do(self):
        await tornado.gen.sleep(1)
        return ' --- 123'

其中相关的替换就是 def => async def, 去掉装饰器 @tornado.gen.coroutine,yield / yield from => await 。

关于 gen.coroutine 和 future 为了兼容这种语法的关键是:

# tornado/gen.py
def _make_coroutine_wrapper(func, replace_callback):
    # 实现兼容 async
    wrapped = func
    if hasattr(types, 'coroutine'):
        func = types.coroutine(func)

    ....

# tornado/concurrent.py
class Future(object):

    ...
    
    # 实现兼容 await
    # Implement the Python 3.5 Awaitable protocol if possible
    # (we can't use return and yield together until py33).
    if sys.version_info >= (3, 3):
        exec(textwrap.dedent("""
        def __await__(self):
            return (yield self)
        """))

最后附上官方文档:PEP 492 -- Coroutines with async and await syntax