Vad*_*rov 2 python python-3.x python-asyncio
您好asyncio专家,
如何正确返回协程的结果?我需要使用return或future.set_result吗?
例如:
@coroutine
def do_something()
result = yield from some_function()
return result
Run Code Online (Sandbox Code Playgroud)
要么
@coroutine
def do_something()
future = asyncio.Future()
result = yield from some_function()
future.set_result(result)
Run Code Online (Sandbox Code Playgroud)
你应该使用return result.你的第二个例子实际上最终将返回None,而不是result.这是一个完整的例子,证明:
from asyncio import coroutine
import asyncio
@asyncio.coroutine
def some_function():
yield from asyncio.sleep(.5)
return 5
@coroutine
def do_something():
result = yield from some_function()
return result
@coroutine
def do_something_else():
future = asyncio.Future()
result = yield from some_function()
future.set_result(result)
@coroutine
def main():
print((yield from do_something()))
print((yield from do_something_else()))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
输出:
5
None
Run Code Online (Sandbox Code Playgroud)
请注意,如果您实际返回Futurefrom ,它们确实与调用者的角度相同do_something_else:
@coroutine
def do_something_else():
future = asyncio.Future()
result = yield from some_function()
future.set_result(result)
return future # Now yield from do_something_else() returns 5.
Run Code Online (Sandbox Code Playgroud)
但是当你可以直接回来时,这只是不必要的额外工作result.
在绝大多数情况下,协同程序根本不需要显式创建Future和调用set_result它.这种模式偶尔会有用,但是你最常在单元测试和框架中看到它,而不是在应用程序代码中.
它的一个有趣用途是实现asyncio.sleep:
@coroutine
def sleep(delay, result=None, *, loop=None):
"""Coroutine that completes after a given time (in seconds)."""
future = futures.Future(loop=loop)
h = future._loop.call_later(delay, future.set_result, result)
try:
return (yield from future)
finally:
h.cancel()
Run Code Online (Sandbox Code Playgroud)
在这里Future创建a,set_result计划在调用者想要休眠之后调用该未来的方法,然后yield from在将来调用,这将使函数等待很长时间delay,此时future.set_result(result)调用,并且yield from通话完成.