Лутц М. - Изучаем Python (1077325), страница 160
Текст из файла (страница 160)
) и, следовательно, соответствуют форме гасве спвсапсе выше. В частности, если вместо экземпляра в инструкции гасве указывается класс, и дополнительный элемент данных ие является экземпляром указанного класса, интерпретатор автоматически вызовет класс с дополнительными элементами данных в качестве аргументов конструктора, чтобы создать и возбудить экземпляр класса исключения.
748 Глава 28, Объекты исключений Например, можно возбудить экземпляр встроенного исключения КеуЕггог, просто записав инструкцию га!ве КеуЕггог: даже при том, что КеуЕггог в настоящее время является классом, — интерпретатор вызовет КеуЕггог, чтобы создать необходимый экземпляр. Фактически исключение КеуЕг го г и любые другие исключения на основе классов можно возбудить различными способами: № обминая форма: аозбумдается экземпляр № Класс, зкзеипляр, используется экземпляр № Класс: будет созда~ экземпляр № Класс, аргумент: будет создан зкзеипляр гатзе КеуЕггог() гагзе КеуЕггог, КеуЕггог() га1зе КеуЕггог гатзе КеуЕггог, Гоаб арам" Для всех этих пяти форм инструкция Г ту, имеющая следующую форму: тгу: ехсерт КеуЕггог, Х: присвоит переменной Х объект экземпляра класса КеуЕг гог.
В заключение В этой главе мы занялись созданием собственных исключений. Здесь мы узнали, что исключения могут быть реализованы как строковые объекты или как экземпляры классов. Однако в настоящее время предпочтение следует отдавать экземплярам классов, а в будущей версии Ру1)топ классы станут единственно возможным способом реализации исключений. Классы исключений предпочтительнее потому, что они поддерживают концепцию создания иерархий исключений (что положительно сказывается на удобстве сопровождения), позволяют присоединять к исключениям дополнительные данные и поведение в виде атрибутов и методов экземпляров, а также обеспечивают наследование атрибутов и методов от суперклассов.
Мы видели, что перехватывая суперкласс в инструкции тту, мы перехватываем этот класс, а также все его подклассы, расположенные ни- Если это объяснение показалось вам малопонятным, просто запомните, что исключения могут идентифицироваться строкой или экземпляром класса. В случае строк вместе с исключением можно передавать дополнительные данные. В случае классов, если объект экземпляра не передается инструкции гаьве, интерпретатор создаст его автоматически. В версии Ру$Ьоп 2.5 можно вообще отказаться от использования строковых форм инструкции гатве, потому что при возбуждении строковых исключений генерируются предупреждения, а, кроме того, они будут недоступны в следующей версии Руеттоп.
Но, к сожалению, обратная совместимость все еще принимается во внимание в книгах, которые обучают языку программирования, используемому более чем одним миллионом человек( 749 Закрепление пройденного же в дереве наследования; суперклассы начинают играть роль названий категорий, а подклассы становятся определенными типами исключений в этих категориях. Мы также видели, что инструкция га1ае поддерживает несколько форматов, хотя большинство современных программ просто создают и возбуждают экземпляры классов. В этой главе мы исследовали обе альтернативы — исключения на основе строк и на основе классов. Тем не менее, объекты исключений проще запомнить, если ограничиться только рекомендуемой моделью, основанной на использовании классов, — описывайте свои исключения как классы, наследуйте класс ЕхсерГ1ол как вершину своих деревьев исключений, — и вы сможете забыть старую альтернативу на основе строк.
Следующая глава завершает эту часть книги и всю книгу в целом исследованием некоторых типичных случаев использования исключений и рассмотрением инструментов, наиболее часто используемых программистами на языке Ру(поп. Однако, прежде чем двинуться дальше, ответьте на контрольные вопросы к этой главе. Закрепление пройденного Контрольные вопросы 1. Как определяется соответствие строковых исключений и обработчиков? 2. Как определяется соответствие исключений на основе классов и обработчиков7 3. Как можно присоединить контекстную информацию к исключениям на основе классов и как ее можно использовать в обработчиках7 4. Как можно определить текст сообщения об ошибке в исключениях на основе классов7 5.
Почему в настоящее время нежелательно использовать исключения на основе строк? Ответы 1. Соответствие строковых исключений выявляется по идентичности объекту (технически, с помощью оператора (з), а не по значению объекта (оператор ==). Поэтому будет недостаточно использовать то же самое значение — необходимо иметь ссылку на тот же самый объект (обычно переменную). Короткие строки в языке Ру(Ьоп кэшируются с целью многократного использования, поэтому использование одного и того же значения может иногда работать, но вы не должны полагаться на это (подробнее об этой проблеме будет рассказываться в конце следующей главы).
2. Соответствие исключений на основе классов определяется отношением к суперклассу: при использовании имени суперкласса в обра- Глава 28. Объекты исключений ботчике исключения будут перехватываться экземпляры этого класса, а также экземпляры всех его подклассов, расположенных ниже в дереве наследования. Благодаря этому суперклассы можно интерпретировать как категории исключений, а подклассы — как более специфичные типы исключений в этих категориях.
3. Присоединение дополнительной информации к исключениям на основе классов производится путем заполнения атрибутов объекта экземпляра исключения, часто внутри конструкторов классов. В обработчиках исключений указывается переменная, которой присваивается экземпляр исключения, после этого имя переменной может использоваться для доступа к присоединенной информации и для вызова любых унаследованных методов класса.
4. Текст сообщения об ошибках в исключениях на основе классов можно определить с помощью метода перегрузки гврг или втг, Если вы наследуете свои классы от встроенного класса Ехсерттоп, в тексте сообщения автоматически будут отображаться все аргументы, переданные конструктору. 5.
Потому что, как заявил Гвидо (ОиЫо), в будущей версии Ру1Ьоп планируется вообще убрать их. На самом деле, для этого есть весьма серьезные основания: строковые исключения не поддерживают деление на категории, не позволяют присоединять информацию о состоянии или наследовать поведение, как исключения на основе классов. С практической точки зрения строковые исключения проще в использовании на первых порах, пока программы достаточно маленькие, но их становится сложно использовать, как только программы становятся больше. Использование исключений Данная глава завершает зту часть книги рассмотрением некоторых тем, связанных с проектированием исключений и примеров их использования.
Далее следует раздел с описанием типичных проблем и упражнения. Поскольку эта глава к тому же является последней главой книги, здесь приводится краткий обзор средств разработки, которые помогут вам пройти путь от начинающего программиста до разработчика приложений на языке РуФпоп.
Вложенные обработчики исключений До сих пор в наших примерах для перехвата исключений использовалась единственная инструкция г гу, но что произойдет, если одну инструкцию Ггу вложить внутрь другой"г И, раз уж на то пошло, что произойдет, если в инструкции 1 гу вызывается функция, которая выполняет другую инструкцию ггуг С технической точки зрения инструкции могут вкладываться друг в друга как синтаксически, так и по пути следования потока управления через программный код. Оба эти варианта проще будет понять, если вы узнаете, что интерпретатор складывает инструкции ггу стопкой во время выполнения.
Когда возникает исключение, интерпретатор возвращается к самой последней инструкции Ггу, содержащей соответствующее предложение ехсерг. Поскольку каждая инструкция ггу оставляет метку, интерпретатор может возвращаться к более ранним инструкциям ггу, двигаясь по стопке меток. Такое вложение активных обработчиков и есть то, что подразумевается, когда мы говорим о распространении исключений вверх, к обработчикам «более высокого уровня«.
Эти обработчики являются обычными инструкциями ггу, в которые поток управления ходом выполнения программы вошел раньше. Глава 29. Использование исключений Рисунок 29.1 иллюстрирует„что происходит, когда возникает вложение инструкций ггу/ехсер1 во время выполнения. Объем программного кода, который выполняется в инструкции 1гу, может оказаться весьма существенным (например, он может содержать вызовы функций) и нередко вызывает другой программный код, который готов перехватить те же самые исключения. Когда исключение наконец возбуждается, интерпретатор переходит к самой последней инструкции ггу, в которой указано имя исключения, запускает блок ехсерг и продолжает выполнение программы ниже этой инструкции ггу.
Как только такое исключение будет перехвачено, его жизнь заканчивается — управление не передается всем соответствующим инструкциям 1гу, содержащим имя исключения, — только первая из них получает возможность обработать исключение. Например, на рис.
29.1 инструкция га1ае в функции Гапс2 возвращает управление обработчику в функции Гопс1, после чего программа продолжает выполнение внутри Гопс1. Напротив, когда исключение возникает во вложенных инструкциях ггу/Гзпа!1у, выполняется каждый блок Г(па11у по очереди — интерпретатор продолжает передавать исключение вверх по цепочке вложенных инструкций с гу, пока не будет достигнут обработчик по умолчанию верхнего уровня (который выводит стандартные сообщения об ошибках). Как показано на рис. 29.2, предложения Г! паПу не останавливают распространение исключений — они лишь определяют программный код, который должен выполняться на выходе из инструкции ггу в процессе движения исключения.
Если к моменту возникновения исключения имелось несколько активных инструкций 1гу/11- па11у, они все будут выполнены, если где-то на пути исключения не встретится инструкция 1гу/ехсер1, которая перехватит его. Другими словами, куда будет выполнен переход при возникновении исключения, полностью зависит от того, где оно возникло, — это определяется ходом выполнения программы, а не только синтаксисом. Рис. 29.1. Вложенные инструкции ггу/ехсер! г когда возбуждается исключение (программой или интерпретатором), происходит возврат к самой последней инструкции ггу с соответствующим предложением ехсерг и программи продолжает выполнение после этой инструкции ггу.