我正在尝试编写一个小的Python脚本,该脚本基本上可以并行运行两件事。我来自JavaScript,试图使用Python的异步/等待协程功能,但是我很难按预期运行它。
使前两个功能并行运行非常容易。我遇到的问题与捕获语法错误有关。
具体来说,我试图在我的函数之一中添加一些数学运算,但是Python似乎只能卡在那一步上(工作前打印,之后不打印)。我将问题归结为语法异常没有像我期望的那样冒泡,特别是,如果异步发生在“ future ”内部,那么异步似乎隐藏了错误。我认为这是我的问题所在,但我曾有一段时间尝试按我的期望捕获错误。
我试图将整个违规协程包装在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”,打印语法错误,然后退出,但是我无法捕获该代码,并且丢失了撤消。
我觉得我缺少一些简单的东西。任何指针将不胜感激。
最佳答案
我在文档中找到了一个引用,即asyncio.run()
应该用作“主”入口点并处理所有循环的创建和清理,因此我尝试了一下。
使用它比事件循环的东西更清楚。以下是我想要的。
asyncio.run(asyncio.wait([test(), other()], return_when=asyncio.FIRST_COMPLETED))
我不明白的是为什么当我较早尝试return_when=asyncio.FIRST_COMPLETED
时它一直运行。也许还有其他错别字我错过了。造成困惑的原因之一是,协程除非有什么等待的地方,否则它们不会运行。
不知道这是否对将来的其他人有帮助。感谢所有看过的人。
关于python - 在Python中使用协同程序正确捕获语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64093973/