Як надрукувати виняток у Python?


Відповіді:


1061

Для 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) на клавішних помилках, здається, дає лише ключ, але не повне повідомлення про виключення, що є менш ніж корисним.
Веггіет

14
Якщо ви збираєтеся надрукувати виняток, краще використовувати print(repr(e)); Базова Exception.__str__реалізація повертає лише повідомлення про виключення, а не тип. Або скористайтеся tracebackмодулем, який має методи для друку поточного винятку, відформатованого або повного сліду.
Martijn Pieters

450

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

3
чи є якийсь дзвінок get_error_message, який я можу друкувати, бачачи, коли я використовую власний режим друку, щоб додати деякі інші речі.
MikeSchem

10
@MikeSchem error_message = traceback.format_exc()
heyzling

3
Дякую, це саме те, що я хотів. Цілий слід, а не лише тип помилки та повідомлення
Кен Беллоуз

Цей фрагмент не використовує захоплений виняток. Чи можете ви розширити код для використання "ex"? - як у except Exception as ex:...
aaronsteers

@aaronsteers він використовує захоплений виняток; у обробнику винятків поточний виняток доступний через sys.exc_info()функцію, і traceback.print_exc()функція отримує його звідти. Вам буде потрібно коли-небудь явно передавати виняток, коли ви не обробляєте виняток або коли ви хочете показати інформацію на основі іншого винятку.
Martijn Pieters

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 , що дозволяє правильно розбирати / перенаправляти вихід / тощо. Я розумію, що питання суворо стосувалося "друку помилки", але, мабуть, важливо вказати на найкращу практику тут, а не залишати цю деталь, яка може призвести до нестандартного коду для тих, хто з часом не вчиться краще.

Я не використовував tracebackмодуль, як у відповіді Cat Plus Plus, і, можливо, це найкращий спосіб, але я подумав, що викину це туди.


1
Я б запропонував додатково додати флеш = True. Я помітив із системою (і не використовуючи належну систему реєстрації журналів), що буферизація під час захоплення до журналу - це не те, чого я б очікував.
Камерон Керр

20

Пітон 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 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'

Друк / Журнал повного відстеження

Як уже згадувалося, ви можете зловити весь слід за допомогою модуля traceback:

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.