我正在试着写一个小的Python脚本,基本上可以并行运行两件事。我来自JavaScript,正在尝试使用Python的async/await协程特性,但我在让它按我期望的方式工作时遇到了一些问题。
让前两个函数并行运行非常容易。我遇到的问题与捕获语法错误有关。
具体地说,我试图在我的一个函数中添加一些数学,但Python似乎只是在这一步上挂起了(在工作之前打印,在它们失败后打印)。我将我的问题追溯到语法异常没有像我预期的那样冒泡,特别是异步似乎隐藏了错误,如果它们发生在“期货”中。我认为这就是我的问题所在,但我花了很长时间才能像我预期的那样捕捉到错误。
我试着用try/except包装整个令人不快的协程,但这似乎破坏了我的其他协程(似乎打破了我对协程如何工作的假设)。
#!/usr/bin/env python3
import asyncio
async def other():
while True:
await asyncio.sleep(1)
print('foobar')
async def test():
try:
while True:
a = undefinedVariable
except:
print("Why doesn't this always catch??")
# catches as expected
asyncio.get_event_loop().run_until_complete(asyncio.wait([test()]))
# doesn't catch, fills screen with "foobar" lines, once a second, runs forever
asyncio.get_event_loop().run_until_complete(asyncio.wait([test(), other()]))
# Trying other things...
# Error:
# RuntimeError: no running event loop
# sys:1: RuntimeWarning: coroutine 'test' was never awaited"
asyncio.get_event_loop().run_until_complete(asyncio.wait([asyncio.create_task(t()) for t in [test, other]]))运行一个有问题的协程就像预期的那样。
将它与另一个不出错的协程相结合,会使另一个协程停止对asyncio.sleep的尊重。
我曾经遇到过这样的情况,如果我点击Ctrl+C,它将停止打印"foobar",打印语法错误,然后退出,但我未能捕获该代码,它将丢失到撤销。
我觉得我错过了一些简单的东西。如果有任何建议,我们将非常感谢。
发布于 2020-09-28 07:53:44
我在文档中发现了一个引用,即asyncio.run()应该用作“主”入口点,并处理所有循环的创建和清理,所以我尝试了一下。
使用它比使用事件循环的东西更清晰一些。下面的代码就是我想要的。
asyncio.run(asyncio.wait([test(), other()], return_when=asyncio.FIRST_COMPLETED))我不明白的是为什么当我之前尝试return_when=asyncio.FIRST_COMPLETED的时候,它一直在运行。也许我还漏掉了一些其他的打字错误。
造成混乱的一个原因是协程不会运行,除非有东西在等着它们。
不确定这是否能在未来帮助其他人。感谢所有看过的人。
https://stackoverflow.com/questions/64093973
复制相似问题