1

我想解析异常打印,以便不会出现所有异常数据。

例如,我有以下异常消息:

Traceback(最近一次调用最后一次):文件“C:\flow_development\console_debug_sample.py”,第 52 行,在 raise Exception('Exception occur') Exception: Exception occur

我想解析这个异常,只有异常消息会出现:

发生异常

为此我用来编码:

class Unbuffered:
    def __init__(self, stream):
        self.stream = stream
    def write(self, data):
        self.stream.write(data)
        self.stream.flush()
    def __getattr__(self, attr):
        return getattr(self.stream, attr)

if __name__ == "__main__":
    sys.stdout = Unbuffered(sys.stdout)
    sys.stderr = Unbuffered(sys.stderr)

    raise Exception('Exception occur')

但是,异常的每一行都分别调用了“write”函数,所以我无法刷新所有异常消息并进行解析。

任何的想法 ?

4

2 回答 2

1

最简单的方法是更改sys.excepthook​​函数:

import sys

def my_hook(exc_type, exc_value, exc_tb):
    sys.stderr.write('{}: {}\n'.format(exc_type.__name__, exc_value))
    sys.stderr.flush()
    sys.exit(-1)


sys.excepthook = my_hook

在此更改之后,每当引发未捕获的异常时,将不会打印回溯并且程序将退出:

>>> raise RuntimeError('ARGHHH!!!')
RuntimeError: ARGHHH!!!

如果要替换sys.stderr以执行此操作,则必须检查是否正在打印回溯。例如:

class NastyStderr(object):
    def __init__(self, stream):
        self.stream = stream
        self.printing_traceback = False
    def write(self, data):
        if self.printing_traceback:
            if not data.startswith('  '):
                self.stream.write(data)
                self.stream.flush()
                self.printing_traceback = False
        else:
            if data.startswith('Traceback'):
                self.printing_traceback = True
            elif not data.startswith('\nDuring handling'):
                self.stream.write(data)
                self.stream.flush()
    def __getattr__(self, attr):
        return getattr(self.stream, attr)

用作:

>>> sys.stderr = NastyStderr(sys.stderr)
>>> raise ValueError('A')
ValueError: A
>>> try:
...     raise RuntimeError('A')
... except Exception as e:
...     raise ValueError('B')
... 
RuntimeError: A
ValueError: B

正如您在第二个示例中看到的那样,它会打印发生的两个异常。编写一个NastyStderr能够理解它应该只打印第二个的将是相当困难的。

但是,更改sys.excepthook解决方案以在回溯中打印所有异常非常简单:

>>> import sys
>>> def my_hook(exc_type, exc_value, exc_tb, exit=True):
...     if exc_value.__context__ is not None:
...             prev = exc_value.__context__
...             my_hook(prev.__class__, prev, prev.__traceback__, exit=False)
...     sys.stderr.write('{}: {}\n'.format(exc_type.__name__, exc_value))
...     sys.stderr.flush()
...     if exit:
...             sys.exit(-1)
... 
>>> sys.excepthook = my_hook
>>> try:
...     raise Exception('A')
... except Exception:
...     raise ValueError('B')
... 
Exception: A
ValueError: B
于 2013-09-09T06:29:53.453 回答
0

你总是可以捕捉到异常。如果您不想打印所有消息,只需捕获异常并打印您的消息。

例如。

import sys
class Unbuffered:
    def __init__(self, stream):
        self.stream = stream
    def write(self, data):
        self.stream.write(data)
        self.stream.flush()
    def __getattr__(self, attr):
        return getattr(self.stream, attr)

if __name__ == "__main__":
    try:
       sys.stdout = Unbuffered(sys.stdout)
       sys.stderr = Unbuffered(sys.stderr)

       raise Exception('Exception occur')
    except Exception:
       print 'Exception occur'
于 2013-09-09T06:24:35.877 回答