Python 异步:return 与 set_result
Python asyncio: return vs set_result
你好 asyncio 专家,
如何从协程中正确地 return 结果?我需要使用 return 还是 future.set_result?
例如:
@coroutine
def do_something()
result = yield from some_function()
return result
或
@coroutine
def do_something()
future = asyncio.Future()
result = yield from some_function()
future.set_result(result)
你应该只使用 return result
。您的第二个示例实际上将以 returning 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())
输出:
5
None
请注意,如果您实际上 return 来自 do_something_else
:
的 Future
,那么从调用者的角度来看,它们确实是等效的
@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.
但是当你可以直接 return 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()
这里创建了一个 Future
,该未来的 set_result
方法被安排在调用者想要休眠多长时间后调用,然后 yield from
在未来被调用,这将使函数等待 delay
的时间,此时 future.set_result(result)
被调用,并且 yield from
调用完成。
你好 asyncio 专家,
如何从协程中正确地 return 结果?我需要使用 return 还是 future.set_result?
例如:
@coroutine
def do_something()
result = yield from some_function()
return result
或
@coroutine
def do_something()
future = asyncio.Future()
result = yield from some_function()
future.set_result(result)
你应该只使用 return result
。您的第二个示例实际上将以 returning 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())
输出:
5
None
请注意,如果您实际上 return 来自 do_something_else
:
Future
,那么从调用者的角度来看,它们确实是等效的
@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.
但是当你可以直接 return 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()
这里创建了一个 Future
,该未来的 set_result
方法被安排在调用者想要休眠多长时间后调用,然后 yield from
在未来被调用,这将使函数等待 delay
的时间,此时 future.set_result(result)
被调用,并且 yield from
调用完成。