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


Ответы:


1065

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

except Exception as e: print(e)

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

except Exception,e: print str(e)

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

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, и, возможно, это лучший способ, но я подумал, что я добавлю это.


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)

1
Не следует использовать внутри обработчика журналов, чтобы избежать RecursionError
— Prakhar Pandey

4

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

assert type(A) is type(""), "requires a string"

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'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.