2013-09-09 3 views
1

Я хочу проанализировать печать исключения, чтобы не отображались все данные исключения.Python stderr - сообщение об исключении синтаксического анализа

, например, у меня есть следующее сообщение об исключении:

Traceback (самый последний вызов последнего): Файл "C: \ flow_development \ console_debug_sample.py", строка 52, в рейза Exception (» исключение происходит ') исключение: исключение происходит

, и я хочу, чтобы разобрать это исключение, которое будет отображаться только сообщение об исключении:

Исключение происходит

для этого я использую код:

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

Но, каждая строка в исключения вызова функции «записи» по отдельности, так что я не могу смывать все сообщения исключений и разобрать.

Любая идея?

+1

Почему на земле вы хотите сделать это? Вы понимаете, что вы скрываете * много полезной информации? На самом деле, если вы когда-либо открываете вопрос о SO и делаете * не * предоставляете * полные * исключения, то трассирующие люди (включая меня) * будут * спрашивать вас об этом. Поэтому я надеюсь, что вы делаете это только потому, что хотите экспериментировать с обработкой исключений, а не для реального использования. – Bakuriu

ответ

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 решение для того, чтобы напечатать все исключения в TRACEBACK:

>>> 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 
+0

Спасибо !!!!работает как шарм :-) и как мне вернуть sys.excepthook на значение по умолчанию? – EitanG

+0

@EitanG Существует аргумент 'sys .__ excepthook__', который можно использовать для восстановления значения по умолчанию (как и большинство других атрибутов). – Bakuriu

+0

@EitanG Если вы нашли мой ответ полезным, вы должны [проголосовать за него] (http://stackoverflow.com/help/why-vote). Если он решает вашу проблему, вы должны [принять ответ] (http://stackoverflow.com/help/accepted-answer). – Bakuriu

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'