摘要.
参考: 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')