捕获无法捕获的异常并重新读取

2024-10-01 11:23:06 发布

您现在位置:Python中文网/ 问答频道 /正文

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

一种可能的方法是修复所有有问题的异常,正如在该问题中所讨论的那样。这不是一件容易的事,因为我们不可能轻易地提前知道哪些异常可以被调用。另一种方法是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和unpickle,然后抛出它,给出错误

^{pr2}$

学分到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。但是,此异常不需要特殊处理。在


Tags: 方法inselfinfomessage错误sysexception
1条回答
网友
1楼 · 发布于 2024-10-01 11:23:06

您可以重写^{}以获得所需的结果。它至少在这个例子中有效,但它相当粗糙,所以请测试,不要承诺:-)

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)):

^{pr2}$

那么这个:

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

相关问题 更多 >