我知道在JS中,
如果两者不相等,那么最佳实践是什么?
return
语句前加上await
没有任何作用(即return await ...
),但在Python中是否也是如此,或者这样做会使材料化更有可能或不同?如果两者不相等,那么最佳实践是什么?
return
语句前加上await
没有任何作用(即return await ...
),但在Python中是否也是如此,或者这样做会使材料化更有可能或不同?给定:
async def foo() -> str:
return 'bar'
调用foo
函数后得到的是一个Awaitable
对象,显然需要使用await
操作符。你需要考虑的是你的函数的返回值。例如,你可以这样做:
def bar() -> Awaitable[str]:
return foo() # foo as defined above
在这里,bar
是一个同步函数但返回一个Awaitable
,该函数将返回一个str
。
async def bar() -> str:
return await foo()
bar
本身是 async
的,并在调用时产生了一个 Awaitable
,结果与上述相同,都是一个 str
。这两种用法之间没有真正的区别。区别出现在下面:async def bar() -> Awaitable[str]:
return foo()
在这个例子中,调用 bar
会返回一个 Awaitable
,它会再次返回一个 Awaitable
,最终返回一个 str
;与之前截然不同。如果你天真地使用上述代码,你将得到这种结果:
>>> asyncio.run(bar())
<coroutine object foo at 0x108706290>
RuntimeWarning: coroutine 'foo' was never awaited
通常情况下,每次调用 async
函数都必须在某个位置进行 await
。如果你有两个 async
函数 (async def foo
和 async def bar
),但是在 bar
中没有 await
,那么调用 bar
的调用者必须进行两次 await
,这将会很奇怪。
asyncio
合并协程,只需要一个await会更有意义吗?这似乎是一个奇怪的设计选择。 - Uriasync
只有一个 await
是非常合理的,这样可以让你完全掌控。 - decezereturn await
来返回一个协程。
Async
函数即使使用普通的return
也会返回一个可等待对象(Awaitable),只有通过调用await
才能获得实际结果。如果没有return await
,则结果将是多余的包装后的Awaitable,并且必须等待两次。参见文档。import asyncio
async def nested():
return 42
async def main():
# Nothing happens if we just call "nested()".
# A coroutine object is created but not awaited,
# so it *won't run at all*.
nested()
# Let's do it differently now and await it:
print(await nested()) # will print "42".
asyncio.run(main())
await
。我不确定Python如何处理它,但是Js只是一门糟糕的语言,在幕后执行许多隐式、反直觉和难以调试的操作。 - freakishreturn
是用来在Monad中包装一个值的。所以如果你的值已经是异步的,你甚至不需要一个return调用。然而在JavaScript和Python中,你必须始终有一个return调用,所以如果你在调用return之前不使用"await"来"解包"异步monad,你最终会得到一个双重包装的值。 - undefined