gpt4 book ai didi

python - 捕获无法处理的异常并重新引发

转载 作者:行者123 更新时间:2023-11-28 17:51:35 24 4
gpt4 key购买 nike

这是对我的问题 Hang in Python script using SQLAlchemy and multiprocessing 的跟进.正如该问题中所讨论的,酸洗异常在 Python 中是有问题的。这通常不是问题,但有一种情况是 python 多处理模块中发生错误。由于 multiprocessing 通过酸洗移动对象,如果在 multiprocessing 过程中发生错误,整个过程可能会挂起,如该问题所示。

一种可能的方法是修复所有有问题的异常,如该问题中所述。这并不容易,因为事先无法轻易知道可能调用哪些异常。另一种方法是 suggested by lbolla in an answer to the question ,就是捕获异常,构造一个等价的无害异常,然后重新抛出。但是,我不确定具体如何执行此操作。考虑以下代码。

class BadExc(Exception):
def __init__(self, message, a):
'''Non-optional param in the constructor.'''
Exception.__init__(self, message)
self.a = a

import sys
try:
try:
#print foo
raise BadExc("bad exception error message", "a")
except Exception, e:
raise Exception(e.__class__.__name__ + ": " +str(e)), None, sys.exc_info()[2]
except Exception, f:
pass

import cPickle
a = cPickle.dumps(f)
l = cPickle.loads(a)
print "raising error"
raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]

此代码对异常进行 pickle 和 unpickles,然后抛出它,给出错误

raising error
Traceback (most recent call last):
File "<stdin>", line 11, in <module>
Exception: BadExc: bad exception error message

归功于 Glenn Maynard's answer to "“Inner exception” (with traceback) in Python?" .这具有重要的内容,即回溯、错误消息和异常类型,因此这可能是最好的。但理想情况下,我想要一些看起来与原始异常完全一样的东西,即

Traceback (most recent call last):
File "<stdin>", line 11, in <module>
__main__.BadExc: bad exception error message

或者更一般地说,异常的名称在前面,而不是Exception。这可能吗?

或者,可以使用 print foo 语句代替 BadExc 类,这会给出一个 NameError。但是,此异常不需要特殊处理。

最佳答案

您可以覆盖 sys.excepthook实现你想要的。它至少适用于这个例子,但它很老套,所以请测试并且不要 promise :-)

import sys

def excepthook_wrapper(type, value, traceback):
if len(value.args) == 2:
name, msg = value.args
value.args = (msg,)
sys.__excepthook__(name, value, traceback)
else:
sys.__excepthook__(type, value, traceback)

sys.excepthook = excepthook_wrapper

(编辑:我对此并不真的满意,因为现在“正常”的带有两个参数的异常也会得到不同的处理。可能的解决方案,“标记”你的通过将“PICKLED”作为第一个参数传递的特殊异常,然后检查它,而不是检查 args 的长度。)

然后使用两个参数创建Exception,名称(__module__.__class__) 和Exception 消息(str( e)):

try:
try:
#print foo
raise BadExc("bad exception error message", "a")
except Exception, e:
cls = e.__class__
if hasattr(cls, '__module__'):
name = '{0}.{1}'.format(cls.__module__, cls.__name__)
else:
name = cls.__name__
raise Exception(name, str(e)), None, sys.exc_info()[2]
except Exception, f:
pass

然后这个:

import cPickle
a = cPickle.dumps(f)
l = cPickle.loads(a)
print "raising error"
raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]

打印:

raising error
Traceback (most recent call last):
File "test.py", line 18, in <module>
raise BadExc("bad exception error message", "a")
__main__.BadExc: bad exception error message

关于python - 捕获无法处理的异常并重新引发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8915995/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com