Python stderr - 无法解析异常消息

时间:2013-09-09 05:50:13

标签: python parsing exception flush

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

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

  

追踪(最近一次通话):     文件“C:\ flow_development \ console_debug_sample.py”,第52行,in       引发异常('异常发生')   例外:发生异常

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

  

发生异常

我用来编码:

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'函数,所以我不能刷新所有异常消息并解析。

有什么想法吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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'