Лутц М. - Изучаем Python (1077325), страница 141
Текст из файла (страница 141)
Еще раз о строках документирования "1 ав; Оооетг. бос с1аве еров; "1 ав: враз. Ооо ог Оосвтг.враз бос оет ветхое(ве1(, агд); "1 ав: враз.ветхое. Ооо ог ве1Ц ветхое. Оос Смотрите обсуждение статических методов класса в главе 26, которые представляют собой исключение из этого правила. Подобно связанным ме- тодам, они также могут выглядеть как обычные функции, потому что оии не ожидают получить экземпляр в первом аргументе. Строки документирования, которые мы подробно рассматривали в главе 14, — это литералы строк, которые присутствуют на верхнем уровне различных структур и автоматически сохраняются интерпретатором Ру$Ьоп в атрибутах бос соответствующих им объектов.
Строки документирования могут присутствовать в модулях, в инструкциях бе(, а также в определениях классов и методов. Теперь, когда мы ближе познакомились с классами и методами, можно изучить короткий, но емкий пример с(освтг»эу — здесь демонстрируются места в программном коде, где могут появляться строки документирования. Все они могут представлять собой блоки в тройных кавычках: 658 Глава 25. Шаблоны проектирования с классами Придется держать в уме: связанные методы и функции обратного вызова В объектах связанных методов вместе с функцией автоматически сохраняется экземпляр класса, поэтому они могут использоваться везде, где используются обычные функции.
Одно из обычных мест, где можно увидеть эту идею в действии, — это программный код, регистрирующий методы как обработчики событий в интерфейсе ТЫп$ег ОШ. Ниже приводится простейший случай: бег Ьапб1ег(); сохраняет инфориацию о состоянии в глобальних переиенних... н1бдет = Вот(оп(техт='враз', созвано=лапб1ег) Чтобы зарегистрировать обработчик события щелчка на кнопке, мы обычно передаем в аргументе с именем соввапб вызываемый объект, который не имеет входных аргументов. Здесь часто используются имена простых функций (и 1авбба-выражения), но можно также передавать и методы классов — при условии, что они будут связанными методами: с1авв МуИ1бдет: Оет папб1ег(ве1(); сохраняет инфориацию о состоянии в ве!т.аттг... Оег вакеитбдетв(ве1(): ь = Во(топ(техт='враз', соввапб=ве1(.папб1ег) Здесь обработчик события — это объект связанного метода, где сохраняются ве1( и Муйтбдет.
Ьапб1е г. Так как аргумент ве1Г ссылается на оригинальный экземпляр, то когда метод Лапб1ег будет вызван для обработки события, он получит доступ к атрибутам экземпляра, где может сохраняться информация о состоянии между событиями. При использовании обычных функций для этих целей, как правило, используются глобальные переменные. Другой способ обеспечения совместимости классов с прикладным интерфейсом, основанным на применении функций, приводится в главе 24, где обсуждается метод перегрузки операторов св11 Рввв Оет Гцпс(агдв): '1 ав: Оосвтг.тцпс. Оос Рава Основное преимущество строк документирования состоит в том, что их содержимое доступно во время выполнения.
То есть, если текст был оформлен в виде строки документирования, можно будет обратиться к атрибуту бос объекта, чтобы получить его описание: 659 Классы и модули »> 1арогС оосвСг »> оосвтг. 6ос '1 ае; оосвСг. 6ос »> оосвег.враз. 6ос '1 ап~ прае оос ог оосвгг.врае, оос »> 6освсг.враз.аеспоо, оос 1 ап враз.аеспоо, оос ог ве1с.ееспоо, оос »> оосвсг.сопс. 6ос 1 ае; оосвсг,гопс. 6ос В главе 14 также обсуждается Ру1)ос — инструмент, который позволяет формировать отчеты из всех этих строк. Строки документирования доступны во время выполнения, но синтаксически они менее гибки, чем комментарии а (которые могут находиться в любом месте программы).
Обе формы несут пользу, и любая документация к программе — это хорошо (при условии, что она точная). Классы и модули Мы завершаем эту главу кратким сравнением предметов обсуждения двух последних частей книги: модулей и классов. Так как оба представляют собой пространства имен, различия между ними бывает трудно заметить сразу.
В двух словах: Модули ° Зто пакеты данных и исполняемого кода. ° Создаются как файлы с программным кодом на языке РуСЬоп или как расширения на языке С. ° Задействуются операцией импортирования. Классы ° Реализуют новые объекты. ° Создаются с помощью инструкции с1авв. ° Задействуются операцией вызова. ° Всегда располагаются внутри модуля. Кроме того, классы поддерживают дополнительные возможности, недоступные в модулях, такие как перегрузка операторов, создание множества экземпляров и наследование. Несмотря на то, что и классы, и модули являются пространствами имен, к настоящему времени вы должны четко понимать, что между ними имеются существенные различия. В заключение В этой главе мы рассмотрели подборку типичных способов комбинирования классов для получения наибольшей пользы от их повторного ис- 660 Глава 25.
Шаблоны проектирования с классами пользования и возможности разбивать крупные задачи на более мелкие части, что обычно относится к проблемам проектирования, которые часто рассматриваются вне зависмости от конкретного языка программирования (хотя язык Ру(Ьоп способен облегчить их решение). Мы изучили приемы делегирования (обертывание объектов в классы- обертки), композиции (управление встраиваемыми объектами), наследования (приобретение поведения от других классов) и некоторые другие не совсем обычные концепции, такие как множественное наследование, связанные методы и фабрики. Следующая глава завершает изучение классов и ООП рассмотрением более сложных тем, связанных с классами. Часть этого материала может быть более интересна для тех, кто пишет инструментальные средства, а не прикладные программы, но зти сведения все же заслуживают того, чтобы с ними ознакомились большинство тех, кто занимается ООП на языке Ру(Поп.
Однако сначала ответьте на контрольные вопросы. Закрепление пройденного Контрольные вопросы 1. Что такое множественное наследование? 2. Что такое делегирование? 3. Что такое композиция? 4. Что такое связанные методы? Ответы 1. Множественное наследование имеет место, когда класс наследует более одного суперкласса, — это удобно для объединения пакетов программного кода, оформленных в виде классов.
2. Делегирование подразумевает обертывание объекта классом-оберткой, который расширяет функциональные возможности обернутого объекта и передает ему выполнение части операций. Класс- обертка сохраняет интерфейс обернутого объекта. 3. Композиция — это прием, который подразумевает наличие контроллера, куда встраиваются и которым управляются несколько объектов. Класс контроллера предоставляет все интерфейсы как свои собственные — это один из способов создания крупных структур с помощью классов. 4. Связанные методы объединяют экземпляр класса и функцию метода — их можно вызывать, не передавая объект экземпляра в первом аргументе, потому что внутри таких методов по-прежнему доступен оригинальный экземпляр.
Дополнительные возможности классов Эта глава завершает шестую часть книги и наше изучение ООП на языке Ру1поп представлением нескольких более сложных тем, связанных с использованием классов: мы рассмотрим возможность создания подклассов встроенных типов, псевдочастные (рэеидорг1ча1е) атрибуты, классы нового стиля, статические функции, декораторы функций и многое другое. Как мы уже знаем, модель ООП в языке РуФЬоп чрезвычайно проста, а некоторые из приемов, представленных в этой главе, настолько сложны и совершенно необязательны к использованию, что вы, возможно, не слишком часто будете встречать их в своей карьере прикладного программиста на языке РуЖоп.
Тем не менее в интересах законченности обсуждения, мы завершим наше обсуждение классов кратким обзором этих возможностей. Как обычно, т.к. это последняя глава в этой части, она завершается сводкой типичных проблем, с которыми сталкиваются программисты при использовании классов, и набором упражнений к этой части. Я советую вам обязательно проработать эти упражнения, чтобы прочнее ухватить идеи, которые мы изучали в этой части. Я также предлагаю вам самостоятельно познакомиться с крупными объектно-ориентированными проектами на языке РуФпоп в дополнение к этой книге.
Как и все в программировании, преимущества ООП становятся более очевидными с обретением опыта. Расширение встроенных типов Помимо реализации объектов новых типов классы иногда используются для расширения функциональных возможностей встроенных типов языка Ру1йоп с целью обеспечения поддержки более экзотических структур данных. Например, чтобы добавить в списки дополнитель- 662 ные методы вставки и удаления, можно создать класс, который обертывает (встраивает) объект списка и экспортирует методы вставки и удаления, которые особым образом обрабатывают список, подобно тому, как реализуется прием делегирования, рассмотренный в главе 25. Начиная с версии Ру1Ьоп 2.2 для специализации встроенных типов можно также использовать наследование, Следующие два раздела демонстрируют оба приема в действии.
Расширение типов встраиванием Помните те функции для работы со множествами, которые мы написали в четвертой части книги"г Ниже показано, как они выглядят, реанимированные в виде класса на языке Ру$[топ. Следующий пример (файл вевшгаррегру) реализует новый тип объектов за счет перемещения нескольких функций в методы и добавления перегрузки нескольких основных операторов. По большей части этот класс просто обертывает список, добавляя дополнительные операции.