Лутц М. - Изучаем Python (1077325), страница 150
Текст из файла (страница 150)
Классификация животным в зоологии. Изучите дерево классов, представленное на рис. 26.1. Напишите шесть инструкций с1авв, которые моделировали бы эту модель классификации средствами наследования в языке РуФ)юп. Затем добавьте к каждому из классов метод вреаК, который выводил бы уникальное сообщение, и метод гер1у в суперклассе Аптюа1, являющемся вершиной иерархии, который просто вызывал бы ве1Е. ВреаК, чтобы вывести текст сообщения, 698 Глава 26. Дополнительные возможности классов Инкапсуляция Сокрытие деталей реализации за интерфейсом объекта предохраняет пользователей класса от необходимости изменять свой программный код.
Организация Классы предоставляют новые локальные области видимости, которые минимизируют вероятность конфликтов имен. Кроме того, они обеспечивают место для естественного размещения программного кода реализации и управления состоянием объекта. Поддержка Классы обеспечивают естественное разделение программного кода, что позволяет уменьшить его избыточность. Благодаря организации и возможности повторного использования программного кода в случае необходимости бывает достаточно изменить всего одну копию программного кода. Непротиворечивость Классы и возможность наследования позволяют реализовать общие интерфейсы и, следовательно, обеспечить единообразие вашего программного кода — такой код легко поддается отладке, выглядит более осмысленно и прост в сопровождении. Полиморфизм Это скорее свойство ООП, чем причина его использования, но благодаря поддержке общности программного кода полиморфизм делает код более гибким, расширяет область его применения и, следовательно, увеличивает его шансы на повторное использование.
Другие И, конечно, причина номер один состоит в том, что упоминание о владении приемами ООП увеличивает шанс быть принятым на работу! (Согласен, я привел эту причину в шутку, но, если вы собираетесь работать на ниве программирования, для вас очень важно будет иметь знакомство с ООП.) И в заключение, не забывайте, что я говорил в начале шестой части: вы не сможете полностью оценить достоинства ООП, пока не будете использовать его какое-то время. Выберите себе проект, изучите большие примеры, поработайте над упражнениями — это заставит вас попотеть над объектно-ориентированным программным кодом, но оно стоит того.
Т11 Исключения и инструменты Основы исключений В последней части книги рассказывается об исключениях, которые, по сути, являются событиями, способными изменить ход выполнения программы. Исключения в языке Ру1Ьоп возбуждаются автоматически, когда программный код допускает ошибку, а также могут возбуждаться и перехватываться самим программным кодом. Обрабатываются исключения четырьмя инструкциями. Эти инструкции мы и будем изучать в данной части книги.
Первая из инструкций имеет две разновидности (ниже они перечислены отдельно), а последняя — является дополнительным расширением до выхода версии Ру$)гоп 2.6: ггу/ехсерг Перехватывает исключения, возбужденные интерпретатором или вашим программным кодом, и выполняет восстановительные операции. 1 гуу'г,1рз11у Выполняет заключительные операции независимо от того, возникло ли исключение или нет.
га1яе Дает возможность возбудить исключение программно. аззегт Дает возможность возбудить исключение программно, при выполнении определенного условия. х11'с!аз Реализует менеджеры контекста в версии Ру1Ьоп 2.6 и выше (в версии 2.5 является дополнительным расширением). Эта тема была оставлена напоследок потому, что для работы с исключениями необходимо знание классов.
Тем не менее, за несколькими Глава 27. Основы исключений исключениями (преднамеренная игра слов), как будет показано ниже, обработка исключений в языке Ру$Ьоп выполняется очень просто, потому что они интегрированы непосредственно в сам язык, как и другие высокоуровневые средства. Одно техническое примечание перед началом: после выхода первого издания этой книги в исключениях произошли два изменения — предложение Г1па11у может теперь присутствовать в инструкции 1 гу вместе с предложениями ехсерг и е1ве, а исключения, определяемые программой, теперь должны быть экземплярами классов, а не простыми строками. В этом издании я опишу и старый, и новый способы работы с исключениями, потому что в существующем программном коде вам еще часто будут встречаться изначальные приемы. Попутно я расскажу, какими путями шло развитие в этой области.
Я также опишу новую инструкцию ныл несмотря на то, что ее официальное появление ожидается только в следующем выпуске Ру$Ьоп. Зачем нужны исключения? В двух словах, исключения позволяют перепрыгнуть через фрагмент программы произвольной длины. Рассмотрим пример с машиной по приготовлению пиццы, о которой говорилось ранее в этой книге. Предположим, что мы более чем серьезно отнеслись к этой идее и действительно построили такую машину.
Чтобы приготовить пиццу, наш кулинарный автомат должен выполнить программу, написанную на языке РуФЬоп: она должна принимать заказ, приготовить тесто, выбрать добавки, выпечь основу и т. д. Теперь предположим, что что-то пошло совсем не так во время «выпекания основы». Возможно, сломалась печь или, возможно, наш робот ошибся в расчетах расстояния до печи и воспламенился. Совершенно очевидно, что нам необходимо предусмотреть быстрый переход к программному коду, который быстро обрабатывает такие ситуации, Кроме того, поскольку в таких необычных условиях у нас нет никакой надежды на успешное окончание процесса приготовления пиццы, мы могли бы также вообще отказаться от выполнения всего плана целиком.
Зто именно то, что позволяют делать исключения: программа может перейти к обработчику исключения за один шаг, отменив все вызовы функций. Исключение — это своего рода «супер-яоФо».' Обработчик исключений (инструкция г гу) ставит метку и выполняет некоторый программный код. Если затем где-нибудь в программе возникает исключе- Если вы испольэовали язык С, вам будет интересно узнать, что исключения в языке Ру»1гоп немного похожи на стандартную для языка С пару фУнкций вес1вР/1опд1вР: инструкция ггу действует как функция ае11аР, а инструкция га1ве как 1опд1ар.
Только в языке Ру»)гоп исключения основаны на объектах и являются стандартной частью модели исполнения. уоз Зачем нужны исключения? ние, интерпретатор немедленно возвращается к метке, отменяя все активные вызовы функций, которые были произведены после установки метки. Код в обработчике исключения может соответствующим образом отреагировать на ситуацию (вызвать пожарных, например). Кроме того, переход к обработчику исключения выполняется немедленно, поэтому обычно нет никакой необходимости проверять коды возврата каждой вызванной функции, которая могла потерпеть неудачу. Назначение исключений В программах на языке Руиюп исключения могут играть разные роли, Ниже приводятся некоторые из них, являющиеся наиболее типичными: Обработка ошибок Интерпретатор возбуждает исключение всякий раз, когда обнаруживает ошибку во время выполнения программы.
Программа может перехватывать такие ошибки и обрабатывать их или просто игнорировать. Если ошибка игнорируется, интерпретатор выполняет действия, предусмотренные по умолчанию, — останавливает выполнение программы и выводит сообщение об ошибке. Если такое поведение по умолчанию является нежелательным, можно добавить инструкцию 1 с у, которая позволит перехватывать обнаруженные ошибки и продолжить выполнение программы после инструкции Сгу. Уведомления о событиях Исключения могут также использоваться для уведомления о наступлении некоторых условий, что устраняет необходимость передавать куда-либо флаги результата или явно проверять их.
Например, функция поиска может возбуждать исключение в случае неудачи, вместо того чтобы возвращать целочисленный признак в виде результата (и надеяться, что этот признак всегда будет интерпретироваться правильно). Обработка особых ситуаций Некоторые условия могут наступать так редко, что было бы слишком расточительно предусматривать проверку наступления таких условий с целью их обработки. Нередко такие проверки необычных ситуаций можно заменить обработчиками исключений. Заключительные операции Как будет показано далее, инструкция С гу/г1лэ11у позволяет гарантировать выполнение завершающих операций независимо от наличия исключений.
Необычное управление потоком выполнения И, наконец, так как исключения это своего рода оператор «яо1о», их можно использовать как основу для экзотического управления потоком выполнения программы. Например, обратная трассировка не является частью самого языка, но она может быть реализована Глава 27. Основы исключений с помощью исключений и некоторой логики поддержки, выпол- няющей раскручивание операций присваивания.' Далее в этой части книги мы увидим примеры этих типичных применений.
А пока начнем с обзора средств языка Ру(йоп, предназначенных для обработки исключений. Обработка исключений: краткий обзор В сравнении с некоторыми другими основными возможностями, которые рассматривались в этой книге, исключения в языке Рус)соп представляют собой чрезвычайно легкий инструмент. Поскольку они так просты, перейдем сразу к первому примеру. Предположим, что мы пишем следующую функцию: »> Се( тетспег(оЬ), 1пеех): гесыгп оь)[1псех) Эта функция делает не так много — она просто извлекает элемент из объекта по заданному индексу. При нормальном стечении обстоятельств она возвращает результат: »> х 'ерае' »> ГеСспег(х, 3) Ф Все Равно, чтп к[33 Однако, если передать функции индекс, выходящий за пределы строки, то при попытке выполнить выражение ос) [[пбех) будет возбуждено исключение.
Обнаруживая выход за пределы последовательности, интерпретатор сообщает об этом, возбуждая встроенное исключение 1поехЕггог: »> Гетспег(х, 4) Тгасесасх (есвС гесепС са11 1азс); Г>1е '<етпсп>", 1спе К сп? Г11е "<есзсп>", 1>ле 2, сп Гесслег 1ппехЕггог: всг1пр сппех РШ сг гапре (1пзехЕггсг: выход индекса эа пределы строки) Поскольку наш программный код не перехватывает это исключение явно, оно возвращает выполнение на верхний уровень программы и вызы- Настоящая обратная трассировка — зто довольно сложная тема, н данная возможность не является частью самого языка Ру(Ьоп (даже с появлением функций-генераторов в версии 2.2), поэтому я не буду больше говорить сб этом.
Грубо говоря, обратная трассировка отменяет все вычисления перед переходом — исключения этого не делают (то есть в переменных, которым было выполнено прнсванванне между моментом выполнения инструкции сгу и до момента возбуждения исключения, прежние значения не восстанавливаются). Если вам любопытна эта тема, обращайтесь к книгам по искусственному интеллекту илн языкам программирования Рго1оя нлн 1соп. Обработка исключений: краткий обзор 705 вает обработчик исключений ло умолчанию, который просто выводит стандартное сообщение об ошибке. К настоящему моменту вы наверняка видели в своих программах подобные сообщения об ошибках.