У меня есть функция, вызываемая основной программой:
try:
someFunction()
except:
print "exception happened!"
но в середине выполнения функции возникает исключение, поэтому он переходит к except
части.
Как я могу точно увидеть, что произошло в том, someFunction()
что вызвало исключение?
except:
(без голыхraise
), за исключением, может быть, один раз для каждой программы, и желательно не тогда.except
предложений, вам не нужно проверять тип исключения, это то, что обычно делается, чтобы действовать в соответствии с конкретным типом исключения.except
блока исключение доступно черезsys.exc_info()
функцию - эта функция возвращает три значения, которые дают информацию об исключении, которое обрабатывается в данный момент.Ответы:
Все остальные ответы указывают на то, что вы не должны ловить общие исключения, но никто, кажется, не хочет говорить вам, почему, что важно для понимания, когда вы можете нарушить «правило». Вот объяснение. По сути, это так, что вы не скрываете
Поэтому, если вы позаботитесь о том, чтобы не делать ничего из этого, можно поймать общее исключение. Например, вы можете предоставить пользователю информацию об исключении другим способом, например:
Так как же поймать общее исключение? Есть несколько способов. Если вы просто хотите объект исключения, сделайте это так:
Удостоверьтесь, что
message
пользователь обратил на себя внимание с трудом! Его печати, как показано выше, может быть недостаточно, если сообщение скрыто во многих других сообщениях. Неспособность привлечь внимание пользователей равносильно проглатыванию всех исключений, и если есть одно впечатление, которое вы должны были оставить после прочтения ответов на этой странице, это то, что это не очень хорошая вещь . Завершение блока исключений с помощьюraise
оператора исправит проблему, прозрачно переосмыслив исключение, которое было перехвачено.Разница между вышесказанным и использованием
except:
без каких-либо аргументов двояка:except:
не дает вам объект исключения для проверкиSystemExit
,KeyboardInterrupt
иGeneratorExit
не пойманы выше код, который , как правило , то , что вы хотите. Смотрите иерархию исключений .Если вам также нужна та же самая трассировка стека, которую вы получаете, если вы не перехватываете исключение, вы можете получить его вот так (по-прежнему внутри предложения исключений):
Если вы используете
logging
модуль, вы можете распечатать исключение в журнал (вместе с сообщением) следующим образом:Если вы хотите копать глубже и исследовать стек, смотреть на переменные и т. Д., Используйте
post_mortem
функциюpdb
модуля внутри блока exc:Я обнаружил, что этот последний метод неоценим при поиске ошибок.
источник
Получите имя класса, к которому принадлежит объект исключения:
и использование функции print_exc () также напечатает трассировку стека, которая является важной информацией для любого сообщения об ошибке.
Как это:
Вы получите вывод, как это:
И после печати и анализа код может решить не обрабатывать исключение и просто выполнить
raise
:Вывод:
И переводчик печатает исключение:
После того как
raise
исходное исключение продолжает распространяться дальше вверх по стеку вызовов. ( Остерегайтесь возможных ловушек ). Если вы возбуждаете новое исключение, то появляется новый (более короткий) след стека.Вывод:
Обратите внимание, что traceback не включает
calculate()
функцию из строки,9
которая является источником исходного исключенияe
.источник
traceback.format_exc()
а такжеe.__class__.__name__
это так жеtype(e).__name__
, как и предложенный ответ выше?Обычно вы не должны отлавливать все возможные исключения,
try: ... except
поскольку они слишком широки. Просто поймайте те, которые ожидаются по любой причине. Если вам действительно нужно, например, если вы хотите узнать больше о какой-то проблеме во время отладки, вы должны сделатьисточник
try: ... except Exception:
множество вещей, например, использование библиотек, зависящих от сети, или массажистку, которая может отправлять ей странные вещи. Естественно, у меня тоже есть правильная регистрация. Это важно, чтобы позволить программе продолжить работу в случае единственной ошибки во входных данных.smtplib
?Если только
somefunction
это не очень плохо закодированная устаревшая функция, вам не нужно то, что вы просите.Используйте несколько
except
предложений, чтобы по-разному обрабатывать различные исключения:Суть в том, что вы не должны ловить общие исключения, а только те, которые вам нужны. Я уверен, что вы не хотите скрывать неожиданные ошибки или ошибки.
источник
Большинство ответов указывают на
except (…) as (…):
синтаксис (правильно), но в то же время никто не хочет говорить о слоне в комнате, где слон - этоsys.exc_info()
функция. Из документации по SYS модуля (курсив мой):Я думаю, что это
sys.exc_info()
можно рассматривать как самый прямой ответ на первоначальный вопрос: как узнать, какой тип исключения произошел?источник
except
. Просто для полнотыexctype, value = sys.exc_info()[:2]
расскажет вам тип исключения, который затем может быть использован вexcept
.try: someFunction () кроме Exception, exc:
источник
exc.__class__.__name__
уже было предложено в ответе Алекса - stackoverflow.com/a/9824060/95735Эти ответы хороши для отладки, но для программного тестирования исключения
isinstance(e, SomeException)
могут быть полезны, так как он также проверяет подклассыSomeException
, так что вы можете создать функциональность, которая применяется к иерархиям исключений.источник
Вот как я обрабатываю свои исключения. Идея состоит в том, чтобы попытаться решить проблему, если это легко, и позже добавить более желательное решение, если это возможно. Не решайте проблему в коде, который генерирует исключение, или в этом коде теряется исходный алгоритм, который должен быть записан в точку. Однако передайте данные, необходимые для решения проблемы, и верните лямбду на тот случай, если вы не можете решить проблему вне кода, который ее генерирует.
На данный момент, поскольку я не хочу касаться цели своего приложения, я не добавил никаких сложных решений. Но в будущем, когда я узнаю больше о возможных решениях (поскольку приложение разработано больше), я мог бы добавить в словарь решений, проиндексированных с помощью
during
.В показанном примере одним из решений может быть поиск данных приложения, хранящихся в другом месте, например, если файл 'app.p' был удален по ошибке.
На данный момент, поскольку написание обработчика исключений не является разумной идеей (пока мы не знаем лучших способов ее решения, потому что дизайн приложения будет развиваться), мы просто возвращаем простое исправление, которое ведет себя так, как будто мы работаем приложение в первый раз (в данном случае).
источник
Чтобы добавить к ответу Лорица, я создал декоратор / упаковщик для обработки исключений и журнал оболочек, какой тип исключения произошел.
Это может быть вызвано для метода класса или отдельной функции с декоратором:
@general_function_handler
Смотрите мой блог о полном примере: http://ryaneirwin.wordpress.com/2014/05/31/python-decorators-and-exception-handling/
источник
Вы можете начать, как рекомендовал Лауриц, с:
а потом просто
print ex
так нравитсяисточник
Фактическое исключение может быть зафиксировано следующим образом:
Вы можете узнать больше об исключениях из Руководства по Python .
источник
Ваш вопрос: «Как я могу точно увидеть, что произошло в someFunction (), которая вызвала исключение?»
Мне кажется, что вы спрашиваете не о том, как обрабатывать непредвиденные исключения в производственном коде (как предполагалось во многих ответах), а о том, как выяснить, что вызывает конкретное исключение во время разработки.
Самый простой способ - использовать отладчик, который может останавливаться там, где происходит неперехваченное исключение, предпочтительно не выходить, чтобы вы могли проверить переменные. Например, PyDev в интегрированной среде разработки Eclipse может сделать это. Чтобы включить это в Eclipse, откройте перспективу Debug, выберите
Manage Python Exception Breakpoints
вRun
меню и проверьтеSuspend on uncaught exceptions
.источник
Просто воздержитесь от перехвата исключения и трассировки, которую печатает Python, сообщит вам, что произошло исключение.
источник