Інші відповіді вказують на те, що не слід ловити загальні винятки, але, здається, ніхто не хоче сказати вам чому, що важливо для розуміння, коли ви можете порушити "правило". Ось пояснення. В основному, це так, що ви не ховаєте:
Тож, поки ви подбаєте про те, щоб не робити жодної з цих речей, добре вловлювати загальний виняток. Наприклад, ви можете надати інформацію про виняток користувачеві іншим способом, наприклад:
- Представляйте винятки як діалоги в графічному інтерфейсі
- Перенесіть винятки з робочої нитки або процесу в керуючу нитку або процес у багатопотоковому чи багатопроцесорному додатку
Тож як зловити загальний виняток? Існує кілька способів. Якщо ви просто хочете об'єкт виключення, зробіть це так:
try:
someFunction()
except Exception as ex:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print message
Переконайтеся, що message
доводиться до відома користувача важко пропустити спосіб! Друк, як показано вище, може виявитися недостатньою, якщо повідомлення буде поховано у багатьох інших повідомленнях. Якщо не привернути увагу користувачів, це рівнозначно проковтненню всіх винятків, і якщо є одне враження, з яким вам слід було б піти, прочитавши відповіді на цій сторінці, це не дуже добре . Закінчення raise
виняткового блоку висловлюванням усуне проблему, прозоро повторно піднявши виняток, що був спійманий.
Різниця між вищезазначеним та використанням просто except:
без будь-якого аргументу двояка:
- Оголений
except:
не дає вам об’єкту виключення для огляду
- Винятки
SystemExit
, KeyboardInterrupt
і GeneratorExit
вони не зачеплені вищенаведеним кодом, який, як правило, те, що ви хочете. Дивіться ієрархію винятків .
Якщо ви також хочете той самий стек-трак, який ви отримаєте, якщо ви не виберете виняток, ви можете отримати такий (як і раніше, крім пункту):
import traceback
print traceback.format_exc()
Якщо ви використовуєте logging
модуль, ви можете надрукувати виняток у журналі (разом із повідомленням) таким чином:
import logging
log = logging.getLogger()
log.exception("Message for you, sir!")
Якщо ви хочете копати глибше і вивчити стек, переглянути змінні тощо, використовуйте post_mortem
функцію pdb
модуля всередині блоку, крім:
import pdb
pdb.post_mortem()
Я знайшов цей останній метод неоціненним при полюванні на помилок.
except:
(без голимиraise
), за винятком, можливо, один раз за програмою, а краще не тоді.