Обработка любых исключений — wxPython #10

автор

Если вы довольно часто используете wxPython, со временем вы поймёте, что некоторые исключения довольно сложно обработать. И причина подобной сложности кроется в том, что wxPython использует для C++ пакетов враппер, который называется wxWidgets. Таким образом ваше приложение превращается в микс C++ и Python. Это значит, что события буквально бьют ключом из C++ в Python и обратно. В зависимости от того, где появляется исключение (со стороны Python или со стороны C++), определяется возможный шанс его обнаружения и обработки.

Обработка исключений

Одним из решений, которое работает в большинстве случаев, является использование sys.excepthook в Python. Мы потратим немного времени на то, чтобы покопаться в этом коде и понять, как вы можете использовать его функциональность.

В данном примере мы создаём панель с кнопкой, которая специально вызовет исключение. Мы обрабатываем исключение посредством переадресации sys.excepthook в нашу функцию MyExceptionHook. Эта функция отформатирует след, оставленный исключением, затем отформатирует само исключение, чтобы сделать его читабельным и затем отобразит диалог с информацией о данном исключении.

Создаём декоратор, обнаруживающий исключения

Robin Dunn, создатель wxPython, считает, что было бы круто, если бы кто-то предоставил ему декоратор, который сможет обрабатывать исключения, который можно будет добавить в качестве примера на вики-страницу wxPython. Моя первая идея относительно декоратора выглядела следующим образом:

В этом коде мы создаём класс, который создаёт logging-инстанцию. Затем мы отменяем метод __call__, чтобы получить возможность вызова метода в хендлере исключений, чтобы обнаружить сами исключения. Проще говоря, здесь мы создаём классовый декоратор. Затем мы декорируем хендлер событий с помощью нашего logging-класса исключений. Это не совсем то, чего хотел мистер Данн, так как декоратору нужно иметь возможность врэппить и другие функции. Так что я немного его отредактировал, ведь мне в голову пришла мысль незначительной корректировки, которую вы можете заметить ниже:

В этот раз метод __call__ может принять любое количество аргументов или ключевых слов-аргументов, что делает его более гибким. Это по-прежнему не то, что хотел видеть мистер Данн, так что он написал следующий пример:

Здесь отображены несколько примеров декоратора. Этот пример демонстрирует более традиционную методологию создания декораторов. В нём также есть немного мета-программирования. Первый пример проверяет то, что на самом деле произошло с тем, что было вызвано. Затем он создаёт логгер и обворачивает вызванное хендлером исключение. До того, как он вернётся к врапнутой функции, эта функция изменится таким образом, что будете иметь то же название и строку данных, что и изначальна функция, которую она оборачивала.

Я надеюсь, что вы сможете отбросить это и использовать functools.wraps вместо предложенного варианта, но впредь я постараюсь выражать свои мысли яснее. А для тех, кто не понял сути, лучше обратить к оригинальным туториалам, там всё изложено немного проще.

Примечание: Если вы запускаете последний пример кода в Python 3, то можете удалить импорт формы __future__*, так как он больше не требуется. Но, если вы вдруг забудете это сделать, ничего страшного не произойдёт.

Итоги

Теперь вы знаете несколько способов обнаружения исключений. Надеюсь, что в создании вашего приложения вам это пригодится. Веселитесь!

Вам может быть интересно

Scroll Up