python - 从 Python 中的线程引发多个异常

标签 python exception

tl;dr 我生成了 3 个线程,每个线程都会抛出一个异常,这是引发所有 3 个异常的最 Pythonic 方式吗?

下面是一个与我正在做的类似的代码示例。

from multiprocessing.pool import ThreadPool

def fail_func(host):
    raise Exception('{} FAILED!!!'.format(host))

hosts = ['172.1.1.1', '172.1.1.2', '172.1.1.3']
pool = ThreadPool(processes=5)
workers = [pool.apply_async(fail_func(host)) for host in hosts]
# join and close thread pool
pool.join(); pool.close()
# get the exceptions
[worker.get() for worker in workers if not worker.successful()]

它最终所做的只是在第一台主机上失败并出现以下回溯:

Traceback (most recent call last):
  File "thread_exception_example.py", line 8, in <module>
    workers = [pool.apply_async(fail_func(host)) for host in hosts]
  File "thread_exception_example.py", line 4, in fail_func
    raise Exception('{} FAILED!!!'.format(host))
Exception: 172.1.1.1 FAILED!!!

但我想要它做的是为每个失败的线程引发多个异常,如下所示:

Traceback (most recent call last):
  File "thread_exception_example.py", line 8, in <module>
    workers = [pool.apply_async(fail_func(host)) for host in hosts]
  File "thread_exception_example.py", line 4, in fail_func
    raise Exception('{} FAILED!!!'.format(host))
Exception: 172.1.1.1 FAILED!!!

Traceback (most recent call last):
  File "thread_exception_example.py", line 8, in <module>
    workers = [pool.apply_async(fail_func(host)) for host in hosts]
  File "thread_exception_example.py", line 4, in fail_func
    raise Exception('{} FAILED!!!'.format(host))
Exception: 172.1.1.2 FAILED!!!

Traceback (most recent call last):
  File "thread_exception_example.py", line 8, in <module>
    workers = [pool.apply_async(fail_func(host)) for host in hosts]
  File "thread_exception_example.py", line 4, in fail_func
    raise Exception('{} FAILED!!!'.format(host))
Exception: 172.1.1.3 FAILED!!!

有没有Pythonic的方法可以做到这一点?或者我是否需要将所有内容包装在 try/except 中,收集所有消息,然后重新引发单个异常?

最佳答案

没有办法“引发多个异常”。在给定的异常上下文中,要么存在异常,要么不存在。

所以,是的,您必须创建一个包含所有异常的包装异常,并引发它。但您几乎已经获得了所需的所有代码:

def get_exception():
    try:
        worker.get()
    except Exception as e:
        return e

现在,而不是:

[worker.get() for worker in workers if not worker.successful()]

...你可以这样做:

[get_exception(worker.get) for worker in workers if not worker.successful()]

这是一个异常(exception)列表。


就我个人而言,我一直认为 AsyncResult 应该有一个 exception 方法,类似于 concurrent.futures.Future 中的方法。 。但我会首先在这里使用 futures (如果我被迫使用 Python 2.x,则安装 backport)。

关于python - 从 Python 中的线程引发多个异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18282906/

相关文章:

python - 使用 Pyside 和 Qt Designer 在 QTableView 中创建组合框

python - 为什么 TensorFlow 总是使用 GPU 0?

python - 使用不带引号的字符串将文本文件解析为 python

python - Python实时监控Syslog

Java 网络问题 : java.net.ConnectException:连接被拒绝:连接

c++ - 关于 C++ 构造函数中异常的混淆

java - 如何解决 java.lang.NoClassDefFoundError?

java - 强制应用等待发送新短信

python - 我的 python 程序是否有任何特定方法可以从被杀死的行继续执行?

python - pygame中的全局变量麻烦