琢磨不出来就问,请教 concurrent.futures 并行,进程抛出异常后,如何获取异常消息为 String?

2020-07-11 10:59:58 +08:00
 uti6770werty
TestProcess =  ProcessPoolExecutor(max_workers=5)
TestProcessRet = TestProcess.submit(TestCount,1,2,3)

# 如果 TestProcess 池的任务抛出了异常,
if TestProcess.running() != True:
    if TestProcess.done() == True:
        if TestProcess.exception():
            print(type(TestProcess.result()))
            print(TestProcess.exception())
            # 想把异常的内容转为 String 类型做处理,请教应该如何实现?
            # 上面两种类型,似乎都无法直接获取内容?
545 次点击
所在节点    Python
4 条回复
oahebky
2020-07-15 17:48:14 +08:00
了解一下:

https://paste.ubuntu.com/p/zJmWshSnjZ/


👆 看看是不是你想要的效果。
uti6770werty
2020-07-16 12:59:59 +08:00
@oahebky 非常感谢大大的思路介绍,也感谢您在另外一贴的提点(刚刚才看到。。。)

大大的思路非常的好,try 能做到,效果达到了,略有不同,至于为什么,水平有限也不知道是怎么回事,但异常的内容已经能拿到 String 内容了。。。

```
if exc_futures[i].running() != True:
if exc_futures[i].done() == True: # 如果运行结果是 done()
if exc_futures[i].exception():
try:
_ = exc_futures[i].result()
except Exception as e:
print(len(str(e.__cause__)))

```

直接:
except RuntimeError as e:
print(f'got you, exceptions of sub-process with msg: "{str(e)}"')
直接拿 e 是不会有内容的,
我的是 Python 3.6.6,
uti6770werty
2020-07-16 13:00:32 +08:00
特此报告~@oahebky
oahebky
2020-07-16 15:09:36 +08:00
@uti6770werty
======
回复:

"直接拿 e 是不会有内容的"

如果你函数(子进程内)抛出的异常没有内容(如 `raise ValueError()`)自然 `str(e)` 是空的。

可以考虑使用 repr(e) 代替 str(e),内容更详细(不过得到的字符串有可能是多行的)。

这一部分说明你对异常怎么使用还没有仔细看过,推荐你看一下《 learning python 》(有中文版) 的异常一章(在整书靠后的位置)。

==============

另外,至于为什么要用 `try: exc_futures[i].result() except Exception as e: print(f"Error: {str(e)}")` 这样的写法。
是我看到你这个问题去看 `concurent.futures` package 中 ProcessPoolExecutor 的源码实现来回答的。

简单总结就是 pool 中的子进程内部发生的异常,在执行 `.result()` 的时候,“被提升”到了调用的进程(父进程)上面,从异常输出看过去就像父进程发生异常一样。

这么做的好处有几点,最明显的一点就是异常消息提供的信息和普通的函数调用异常消息一致,比较好定位错误。
另外就是功能较复杂的情况下,可以自己定义异常类,然后子进程抛出,父进程可以捕获精细的异常类做处理,这一点随着对 python 使用的加深还有看看我前面说的那本书那一章,会知道怎么操作的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/689114

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX