Лутц М. - Изучаем Python (1077325), страница 156
Текст из файла (страница 156)
В Крити аская секция программного када ...доступ к совместно использувими раоуроаи.. Здесь механизм управления контекстом гарантирует, что блокировка автоматически будет приобретена до того, как начнет выполняться блок, и освобождена по завершении работы блока. Модуль бес1эа1 (подробнее о числах с фиксированной точностью представления рассказывается в главе 5) также использует менеджеры контекста для упрощения сохранения и восстановления текущего контекста вычислений, определяющего параметры точности и округления, используемые в вычислениях. Протокол управления контекстом Интерфейс, который должны реализовать объекты для использования совместно с инструкцией н(гл, достаточно сложен, хотя большинству программистов достаточно лишь знать, как используются существующие контексты менеджеров.
Однако разработчикам программных инструментов может потребоваться знание правил создания новых менеджеров, поэтому коротко рассмотрим основные принципы. Ниже описывается, как в действительности работает инструкция нг тп: 1. Производится вычисление выражения, возвращающего объект, известный как менеджер контекста, который должен иметь методы Еятаг и Ех)1 2. Вызывается метод ептег менеджера контекста. Возвращаемое значение метода присваивается переменной — при наличии предложения аа, в противном случае оно просто уничтожается.
3. Затем выполняется блок программного кода, вложенный в инструкцию нато. 4. Если при выполнении блока возбуждается исключение, вызывается метод ехт1 (тип, значение, диагностическая информация),которо- КонтекСтные менеДжеРы чч)1)тггав 729 му передается подробная информация об исключении. Обратите внимания, что это те же самые значения, которые возвращает функция вув. ехс Тп(о, описываемая в руководстве по языку Ру1йоп и далее в этой книге.
Если этот метод возвращает ложное значение, исключение возбуждается повторно, в противном случае исключение деактивируется. Обычно исключение следует возбуждать повторно, чтобы оно могло выйти за пределы инструкции н(ТЬ. б. Если в блоке н(ТЬ исключение не возникает, метод ехтт все равно вызывается, но в аргументах тип, значение и диагностическая инфориапип ему передается значение Вопе. Рассмотрим небольшой пример, демонстрирующий работу протокола. Следующий фрагмент определяет объект менеджера контекста, который сообщает о входе и выходе из блока программного кода любой инструкции н(ТЬ, с которой он используется: тгое (отме (арогт иып втатеаепт № требуетоп е Ругггоп 2.5 с1авв ТгасеВ1оск: Оет аевваце(ве1(. агц): ргпп 'гопптпц', агц оег ептег (ве1(). рг1пт 'втагттпц нттп Ь)оск' гетогп ве1" оег ех11 (ве1г, ехс туре, ехс ча1ое, ехс ть): тт ехо туре тв Иопе рг1пт 'ехыео посев!1у1п' е1ве. ргтпт 'гатве ап ехсерттоп', ехс туре гегогп еа1ве № ргораца(е иттп тгасеВ1осх() ав аст(оп ар(топ.аевваце('тевт т ) ргтпт 'геаспео иттп тгасеВ1осх() ав аст(оп асттоп аевваце('тевт 2 ) гатве ТуреЕггог ргтпт 'пот геаспео Обратите внимание, что метод ехтт должен возвращать Га1ве, чтобы разрешить дальнейшее распространение исключения — отсутствие инструкции ге( огп обеспечивает тот же самый эффект, потому что в этом случае по умолчанию возвращается значение Воре, которое по определению является ложным.
Кроме того, следует заметить, что метод ептег возвращает сам объект ве1(, который присваивается переменной в предложении ав; при желании этот метод может возвращать совершенно другой объект. При запуске этого фрагмента менеджер контекста с помощью своих методов ептег и ех11 отмечает моменты входа и выхода из блока инструкции н1ТЬ: Глава 27. Основы исключений 7ЗО % рутпоп выпав, ру втагыпц и1ср о)оск гопптпц сев( 1 геаспеб ехт(ес погаа1!у втагыпц и(тп о1оск гопп1пд тевт 2 гатве ап ехсер(1оп! <(уре 'ехсерыопв.ТуреЕггог'> тгасеоаск (аозт гесепт са11 1авт): Рт!е "С:т'Рутпоп25титтпав.ру".
1(пе 22, тп <аобо1е> гатве ТуреЕггог ТуреЕггог Придется держать в уме: проверка ошибок Один из способов увидеть, насколько полезными могут быть исключения, состоит в том, чтобы сравнить стили программирования на языке Ру1Ьоп и на языке, не имеющем исключений. Например, если вы хотите написать надежную программу на языке С, вам потребуется проверять возвращаемые значения или коды состояния после выполнения каждой операции, которая может быть выполнена с ошибкой, и передавать результаты проверок в ходе выполнения программы: г() № Программа на лемке С (боР1гвтТп1пдп == ЕРРОР) № Проверить наличие оаибки гегогп ЕРРОР; № даже если здесь она не обрабатмеается (боиехттптпцп == еРРОР) гетогп ЕРРОР; бсцтот гетега бо(авттптпд(): ) аатп() ( т( (боБ(отт() == ЕРРОР) ЬабЕпбтпд(): Менеджеры контекста являются новейшими инструментами, которые официально еще не стали частью языка Ру1Ьоп, поэтому мы не будем рассматривать здесь дополнительные подробности (за полной информацией обращайтесь к стандартным руководствам по языку; например, новый стандартный модуль соптех11ТЬ содержит дополнительные средства, которые могут использоваться для создания менеджеров контекстов).
В более простых случаях инструкция тгу!Гтпа11у обеспечивает достаточную поддержку для выполнения завершающих действий. 731 В заключение е1эе дообЕпбзпд(); Фактически в настоящих программах на языке С значительная доля всего программного кода выполняет проверку наличия ошибок. Но в языке РуЕЬоп такая настойчивость и методичность не требуется.
Достаточно просто обернуть произвольные участки программы обработчиками исключений и писать зти участки в предположении, что никаких ошибок возникать не будет: бе( боБ(о(Г(): № Лрограимный код на языке Рутооп богзгэ(ТПгпд() № Нас не беспокоят возиовные исключения, боМех(ТПтпд() № поэтому мозно не выполнят~ проверку боЕдзттотпд() з( папе == ' юагп тгу. боБто(Г() № Здесь нас интересуют возмовные резул~таты, ехсерг: № поэтому зто единственное место, где нувна проверка ЬабЕпбзпд() е1эе; дообЕпбзпд Так как в случае исключения управление немедленно будет передано обработчику, здесь нет никакой необходимости разбрасывать проверки по всему программному коду, чтобы обезопасить себя от ошибок.
Кроме того, благодаря тому, что интерпретатор РуЕЬоп автоматически обнаруживает ошибки, ваши программы обычно не требуют выполнять подобные проверки вообще. Таким образом, исключения позволяют в значительной степени игнорировать возможные необычные ситуации и отказаться от использования программного кода, выполняющего проверки на наличие ошибок. В заключение В етой главе мы приступили к изучению вопросов обработки исключений и к исследованию инструкций, связанных с исключениями; инструкция 1 ту используется для перехвата исключений, газ эе используется для их возбуждения, аээе г1 используется для возбуждения исключений по условию и нзТЛ используется для обертывания программного кода менеджерами контекстов, определяющими действия на входе и выходе.
Пока исключения выглядят достаточно простым инструментом, впрочем, таковым они и являются, — единственная сложность заключается в их идентификации. Следующая глава продолжит наши исследования описанием реализации наших собственных объектов исключений, где будет показано, что классы позволяют создавать исключения более Глава 27. Основы исключений полезные, чем простые строки.
Однако, прежде чем двинуться вперед, ответьте на контрольные вопросы по темам, охваченным в этой главе. Закрепление пройденного Контрольные вопросы 1. Для чего служит инструкция с гу2 2. Какие две основные разновидности инструкции с гу существуют2 3. Для чего служит инструкция га(ве2 4. Для чего служит инструкция аввег( и какую другую инструкцию она напоминает2 5. Для чего служит инструкция н(СП/ав и какие другие инструкции она напоминает2 Ответы 1.
Инструкция тгу служит для перехвата исключений и проведения восстановительных действий после них. Она определяет блок выполняемого программного кода и один или более обработчиков исключений, которые могут возникнуть в ходе выполнения блока. 2. Существует две основные разновидности инструкции (гу — это С гу/ехсерс/е! ве (используется для перехвата исключений) и с г у/(1па11 у (используется для указания завершающих действий, которые должны быть выполнены независимо от того, возникло ли исключение или нет). В версии Ру(Ьоп 2.4 это две отдельные инструкции, которые можно объединить вложением друг в друга.
В версии 2. 5 и выше блоки ехсер! и (1пв11у могут смешиваться в одной и той же инструкции, то есть две формы инструкции объединены в одну. В объединенной форме блок Г(папу по-прежнему выполняется при выходе из инструкции ! г у независимо от того, было обработано исключение или нет. 3. Инструкция гз(ве возбуждает (запускает) исключение. Интерпретатор посредством внутренних механизмов возбуждает встроенные исключения, а ваши сценарии с помощью инструкции га1ве могут возбуждать как встроенные, так и свои собственные исключения.
4. Инструкция авве гг возбуждает исключение АзвегшопЕггог, когда условное выражение возвращает ложное значение. Она напоминает инструкцию га(ве, обернутую инструкций 1Г. 5. Инструкция н1сл/зв предназначена для автоматического запуска программного кода, выполняющего предварительные и завершающие действия перед входом и после выхода из обернутого блока программного кода. Она в общих чертах напоминает инструкцию Сгу/Г1па11у, так как тоже выполняет действия на выходе независимо от того, возникло исключение или нет, но в отличие от последней позволяет определять действия на входе и на выходе, используя для этого протокол, основанный на использовании объектов.