python

async学习笔记

文章暂存

systemime
2020-07-28
3 min

摘要.

参考: https://mozillazg.com/2017/08/python-asyncio-note-coroutines-base-usage.html https://pymotw.com/3/asyncio/coroutines.html

# 启动一个 Coroutine

启动一个 Coroutine 的最简单的一个方法就是使用 asyncio.run_until_complete 函数:

# asyncio_coroutine.py
import asyncio
async def coroutine():
    print('in coroutine')
event_loop = asyncio.get_event_loop()
try:
    print('starting coroutine')
    coro = coroutine()
    print('entering event loop')
    event_loop.run_until_complete(coro)
finally:
    print('closing event loop')
    event_loop.close()


首先是获取一个事件循环,然后用 run_until_complete 执行 Coroutine 对象,当 Coroutine 执行完成并退出时, run_until_complete 也会随后退出。

$ python3.6 asyncio_coroutine.py
starting coroutine
entering event loop
in coroutine
closing event loop

# 获取 Coroutine 的返回值

run_until_complete 会把 Coroutine 的返回值当做自身的返回值返回给调用方:

# asyncio_coroutine_return.py
import asyncio
async def coroutine():
    print('in coroutine')
    return 'result'
event_loop = asyncio.get_event_loop()
try:
    return_value = event_loop.run_until_complete(coroutine())
    print('it returned: {!r}'.format(return_value))
finally:
    event_loop.close()
执行结果:
$ python3.6 asyncio_coroutine_return.py
in coroutine
it returned: 'result'

# 链式调用 Coroutine

即在一个 Coroutine 函数中调用另外的 Coroutine 函数,同时还需要等待这个 Coroutine 函数返回结果。

# asyncio_coroutine_chain.py
import asyncio
async def one():
    print('in one')
    return 'one'
async def two(arg):
    print('in two')
    return 'two with arg {}'.format(arg)
async def outer():
    print('in outer')
    print('waiting for one')
    result1 = await one()
    print('waiting for two')
    result2 = await two(result1)
    return result1, result2
event_loop = asyncio.get_event_loop()
try:
    return_value = event_loop.run_until_complete(outer())
    print('result value: {!r}'.format(return_value))
finally:
    event_loop.close()


可以直接使用 await 等待 Coroutine 返回结果。

$ python3.6 asyncio_coroutine_chain.py
in outer
waiting for one
in one
waiting for two
in two
result value: ('one', 'two with arg one')

# 使用生成器代替 Coroutine

Python 3.5 之前的 Python 3 版本中还没有 async/await 语法,我们可以使用 asyncio.coroutine 装饰器加 yield from 来实现同样的功能:

# asyncio_generator.py
import asyncio
@asyncio.coroutine
def one():
    print('in one')
    return 'one'
@asyncio.coroutine
def two(arg):
    print('in two')
    return 'two with arg {}'.format(arg)
@asyncio.coroutine
def outer():
    print('in outer')
    print('waiting for one')
    result1 = yield from one()
    print('waiting for two')
    result2 = yield from two(result1)
    return result1, result2
event_loop = asyncio.get_event_loop()
try:
    return_value = event_loop.run_until_complete(outer())
    print('result value: {!r}'.format(return_value))
finally:
    event_loop.close()

执行结果:
$ python3.4 asyncio_generator.py
in outer
waiting for one
in one
waiting for two
in two
result value: ('one', 'two with arg one')
上次编辑于: 2021/5/20 下午3:26:49