Как напечатать исключение в Python?

Ответы:

1065

Для Python 2.6 и более поздних версий и Python 3.x:

except Exception as e: print(e)

Для Python 2.5 и более ранних версий используйте:

except Exception,e: print str(e)
jldupont
источник
41
str( KeyError('bad'))=> 'bad'- не сообщает тип исключения
Дейв
10
print (e) on keyerrors, похоже, дает только ключ, но не полное сообщение об исключении, что не очень полезно.
Вегетарианец
14
Если вы собираетесь распечатать исключение, его лучше использовать print(repr(e)); базовая Exception.__str__реализация возвращает только сообщение об исключении, а не тип. Или используйте tracebackмодуль, который имеет методы для печати текущего исключения, отформатированного или полного обратного отслеживания.
Мартин Питерс
453

tracebackМодуль предоставляет методы для форматирования и печати исключений и их tracebacks, например , это будет печатать исключение , как делает обработчик по умолчанию:

import traceback

try:
    1/0
except Exception:
    traceback.print_exc()

Вывод:

Traceback (most recent call last):
  File "C:\scripts\divide_by_zero.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero
Cat Plus Plus
источник
4
есть ли какой-то вызов get_error_message, который я могу распечатать, увидев, как я использую свою собственную процедуру печати, чтобы добавить некоторые другие вещи.
MikeSchem
11
@MikeSchem error_message = traceback.format_exc()
heyzling
3
Спасибо, это тот, который я хотел. Весь след, а не только тип ошибки и сообщение
Кен Беллоуз
Этот фрагмент не использует захваченный объект исключения. Можете ли вы расширить код для использования «ex»? - как в except Exception as ex:...
aaronsteers
@aaronsteers использует захваченное исключение; в обработчике исключений текущее исключение доступно через sys.exc_info()функцию, и traceback.print_exc()функция получает его оттуда. Вам только когда-либо понадобится явно передать исключение, когда не обрабатываете исключение или когда вы хотите показать информацию, основанную на другом исключении.
Мартин Питерс
169

В Python 2.6 или выше это немного чище:

except Exception as e: print(e)

В старых версиях это все еще вполне читабельно:

except Exception, e: print e
илья н.
источник
15
В python3 необходимо использовать 1-й способ с «как».
Сэм Уоткинс
53

Если вы хотите передать строки ошибок, вот пример из ошибок и исключений (Python 2.6)

>>> try:
...    raise Exception('spam', 'eggs')
... except Exception as inst:
...    print type(inst)     # the exception instance
...    print inst.args      # arguments stored in .args
...    print inst           # __str__ allows args to printed directly
...    x, y = inst          # __getitem__ allows args to be unpacked directly
...    print 'x =', x
...    print 'y =', y
...
<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
Ник Дандулакис
источник
38

(Я собирался оставить это как комментарий к ответу @ jldupont, но у меня недостаточно репутации.)

Я видел ответы вроде @ jldupont и в других местах. FWIW, я думаю, важно отметить, что это:

except Exception as e:
    print(e)

выведет вывод ошибки sys.stdoutпо умолчанию. Более подходящим подходом к обработке ошибок в целом будет:

except Exception as e:
    print(e, file=sys.stderr)

(Обратите внимание, что вам нужно, чтобы import sysэто работало.) Таким образом, STDERRвместо этого STDOUTвыводится сообщение об ошибке , что позволяет правильно анализировать / перенаправлять вывод / etc. Я понимаю, что вопрос был строго о «печати ошибки», но, кажется, важно указать здесь лучшую практику, а не пропустить эту деталь, которая может привести к нестандартному коду для тех, кто в конечном итоге не научится лучше.

Я не использовал этот tracebackмодуль, как в ответе Cat Plus Plus, и, возможно, это лучший способ, но я подумал, что я добавлю это.

Grish
источник
1
Я бы предложил дополнительно добавить flush = True. Я заметил, что при использовании systemd (а не при использовании надлежащей структуры ведения журналов) буферизация при записи в журнал не соответствует ожиданиям.
Кэмерон Керр
20

Python 3: logging

Вместо использования базовой print()функции loggingдля регистрации исключения можно использовать более гибкий модуль. В loggingмодуле предлагает много дополнительных функциональные возможности , например , сообщения протоколирования в данном файл журнал регистрации сообщений с метками времени и дополнительной информацией о том, где произошел каротаж. (Для получения дополнительной информации ознакомьтесь с официальной документацией .)

Регистрация исключения может быть выполнена с помощью функции уровня модуля logging.exception()следующим образом:

import logging

try:
    1/0
except BaseException:
    logging.exception("An exception was thrown!")

Вывод:

ERROR:root:An exception was thrown!
Traceback (most recent call last):
  File ".../Desktop/test.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero 

Ноты:

  • функция logging.exception()должна вызываться только из обработчика исключений

  • loggingмодуль не должен использоваться внутри обработчика регистрации , чтобы избежать RecursionError(спасибо @PrakharPandey)


Альтернативные лог-уровни

Также возможно зарегистрировать исключение на другом уровне журнала, используя аргумент ключевого слова, exc_info=Trueнапример:

logging.debug("An exception was thrown!", exc_info=True)
logging.info("An exception was thrown!", exc_info=True)
logging.warning("An exception was thrown!", exc_info=True)
winklerrr
источник
1
Не следует использовать внутри обработчика журналов, чтобы избежать RecursionError
Prakhar Pandey
4

Если вы хотите этого, вы можете сделать одно исправление ошибки с помощью операторов assert. Это поможет вам написать статически исправимый код и заранее проверять ошибки.

assert type(A) is type(""), "requires a string"
whatnick
источник
2

Один из них в значительной степени контролирует, какая информация из трассировки будет отображаться / регистрироваться при перехвате исключений.

Код

with open("not_existing_file.txt", 'r') as text:
    pass

будет производить следующую трассировку:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Распечатать / Записать полный трекбек

Как уже упоминалось, вы можете перехватить всю трассировку, используя модуль трассировки:

import traceback
try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    traceback.print_exc()

Это даст следующий результат:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Вы можете достичь того же, используя ведение журнала:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    logger.error(exception, exc_info=True)

Вывод:

__main__: 2020-05-27 12:10:47-ERROR- [Errno 2] No such file or directory: 'not_existing_file.txt'
Traceback (most recent call last):
  File "exception_checks.py", line 27, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Распечатать / записать имя ошибки / только сообщение

Возможно, вас не заинтересует вся трассировка, а только самая важная информация, такая как имя исключения и сообщение об исключении, используйте:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    print("Exception: {}".format(type(exception).__name__))
    print("Exception message: {}".format(exception))

Вывод:

Exception: FileNotFoundError
Exception message: [Errno 2] No such file or directory: 'not_existing_file.txt'
Джин Тоник
источник