Лутц М. - Изучаем Python (1077325), страница 149
Текст из файла (страница 149)
Где лучше разместить методы конструктора и перегрузки оператора (то есть в каком из классов)? Объекты какого типа смогут складывать ваши классы? На практике гораздо проще написать метод абб, который принимает один действительный аргумент(например, абб(ве1Г, у)) и складывает его с текущими данными экземпляра (например, ве1(. бата + у). Будет ли в такой реализации больше смысла, чем в реализации, которая принимает два аргумента? Можно ли сказать, что это делает ваши классы более «объектно-ориентированными»? 2. Перегрузка операторов. Напишите класс с именем Му1твт, который «обертывает» списки языка РуФоп: он должен перегружать основные операторы действий над списками, включая +, доступ к элементам по индексу, итерации, извлечение среза и такие методы списка, как аррепб и вост.
Полный перечень методов, поддерживаемых списками, вы найдете в справочном руководстве по языку РуФЬоп. Кроме того, напишите конструктор для своего класса, который принимает существующий список (или экземпляр класса Му1! в!) и копирует его в атрибут экземпляра. Поэкспериментируйте со своим классом в интерактивной оболочке. В ходе экспериментов выясните следующее: а. Почему здесь так важно копировать начальное значение? Ь. Можно ли использовать пустой срез (например, в!асс(: )) для копирования начального значения, если им являетея Му1эвс? с. Существует ли универсальный способ передачи управления унаследованным методам списка? й. Можно ли складывать Му1твт и обычный список? А список и Му1твт? Закрепление пройденного б93 е.
Объект какого типа должны возвращать операции сложения и извлечения среза"г А операции извлечения элементов по иидексу7 Г. Если у вас достаточно новая версия Ру(Ьоп (2.2 или выше), вы сможете реализовать такого рода класс-обертку, встраивая настоящий список в отдельный класс нли наследуя класс 1(вг. Какой из двух способов проще и почему г 3. Подклассы. Напишите подкласс с именем Му11в18иЬ от класса Му11вг нз упражнения 2, который расширяет класс Му11вг возможностью вывода сообщения на в1ооьг перед выполнением каждой перегруженной операции и подсчета числа вызовов.
Класс Му1(в13оЬ должен наследовать методы Му11вг. При сложении Му11в18оЬ с последовательностями должно выводиться сообщение, увеличиваться счетчик вызовов операции сложения и вызываться метод суперкласса. Кроме того, добавьте новый метод, который будет выводить счетчики операций на в10оь1, и поэкспериментируйте с этим классом в интерактивной оболочке. Как работают ваши счетчики — считают ли они операции для всего класса (для всех экземпляров класса) или для каждого экземпляра в отдельности г Как бы вы реализовали каждый из этих случаев7 (Подсказка: зависит от того, в каком объекте производится присваивание значения счетчика: атрибут класса используется всеми экземплярами, а атрибуты аргумента ве!г хранят данные экземпляра.) 4. Методы метакласса.
Напишите класс с именем Ме1а с методами, которые перехватывают все обращения к атрибутам (как получение значения, так и присваивание) и выводят сообщения, перечисляющие их аргументы, на в1воШ. Создайте экземпляр класса Мега и поэкспериментируйте с ним в интерактивной оболочке. Что произойдет, если попытаться использовать экземпляр класса в выраженииг Попробуйте выполнить над своим классом операции сложения, доступа к элементам по индексу и получения среза. 5.
Объекты множеств. Поэкспериментируйте с набором классов, описанных в разделе «Расширение типов встраиванием». Выполните команды, которые выполняют следующие операции: а. Создайте два множества целых чисел и найдите их пересечение и об ьединение с помощью операторов $ и ~ . Ь. Создайте множество из строки и поэкспериментируйте с извлечением элементов множества по индексу. Какой метод в классе при этом вызывается г с. Попробуйте выполнить итерации через множество, созданное из строки, с помощью цикла Гог. Какой метод вызывается на этот раз "г г(.
Попробуйте найти пересечение и объединение множества, созданного из строки, и простой строки. Возможно ли это"г е. Теперь расширьте класс множества наследованием, чтобы подкласс мог обрабатывать произвольное число операндов, исполь- 694 Глава 26. Дополнительные возможности классов зуя для этого форму аргумента *згдв. (Подсказка: вернитесь к рассмотрению этих алгоритмов в главе 16.) Найдите пересечение и объединение нескольких операндов с помощью вашего подкласса множества. Как можно реализовать вычисление пересечения трех и более множеств, если оператор 8 работает всего с двумя операндами7 Как бы вы реализовали другие операции над списками в классе множества7 (Подсказка: метод абб перехватывает операцию конкатенации, а метод детаттг может передавать большинство вызовов методов списка в обернутый список.) 6.
Связи в дереве классов. В разделе «Пространства имен: окончание истории«в главе 24 и в разделе «Множественное наследование« в главе 26 я упоминал, что классы имеют атрибут Ьзвев, который возвращает кортеж объектов суперклассов (тех, что перечислены в круглых скобках в заголовке инструкции с1авв). Используя атрибут завез, расширьте класс Е1втег (глава 25) так, чтобы он выводил имена прямых суперклассов экземпляров класса. При этом первая строка в этом выводе должна выглядеть, как показано ниже (значение адреса у вас может отличаться): <1пвтапсе от воб(ворег, Сзвтег), еббгевв 7841200; Как бы вы реализовали вывод значений унаследованных атрибутов7 (Подсказка: у классов имеется атрибут б(ст .) Попробуйте расширить класс Е1втег так, чтобы он выводил список всех доступных суперклассов и их атрибуты (подсказка: порядок подъема по дереву наследования описывается в примере с(аввтгее.ру в главе 24 и в сноске об использовании функций б(г и детзттг в РуФЬоп 2.2 в разделе «Множественное наследование«в главе 26).
7. Композиция. Сымитируйте сценарий оформления заказа в ресторане быстрого питания, определив четыре класса: Еопсб Вмещающий и управляющий класс. Совтошег Действующее лицо, покупающее блюдо. Ешр1оуее Действующее лицо, принимающее заказ.
Еооб То, что приобретает заказчик. Чтобы вам было с чего начать, определите следующие классы и методы: с1авв Сопел; бег зп(К (ве17) Ф Создает и встраивает Созтошег и Ешр1оуее бег огбег(ве1(, тооблаше) л ииитирует приеи заказе бег гево1т(ве1т) Л Запрашивает у клиента название блюда Закрепление пройденного с1азз Созтошег бет им (ве1Г) № Инициализирует название блюда № значением моле Оет О1асесгбег(зе1Г, Гообйаюе, ввр1оуее) № Передает заказ официанту бег ргпк еооб(ве1г) № Выводит название блюда с1авв Еюр1оуее. оег такесгоег(ве!г, гообйаше) № Возврашает блюдо с указанным названием с1азв Еоое: ОеГ тпм (ве!Г, паве) № Сокранлет название блюда Имитация заказа работает следующим образом: а.
Конструктор класса Сопел должен создать и встроить экземпляр класса Совгозег и экземпляр класса Еюр1оуее, кроме того, экспортировать метод с именем огбег. При вызове этот метод должен имитировать прием заказа у клиента (Совгоюег) вызовом метода р1асеОгбег. Метод р1асеОгбег класса Совгоаег должен в свою очередь имитировать получение блюда (новый объект Еооб) у официанта (Евр1оуее) вызовом метода гайеОгбег класса Евр1оуее. Ь. Объекты типа Еооб должны сохранять строку с названием блюда(например, «буррито«), которое передается через Сопел.
огбег в Совгоаег.р1асеОгбег, затем в Еар1оуее.гаКеОгбег и, наконец, в конструктор класса Еооб. Кроме того, класс Сопел должен еще экспортировать метод гево11, который предлагает клиенту (Совгоюег) вывести название блюда, полученного от официанта (еюр1оуее) в результате выполнения заказа (этот метод может использоваться для проверки имитации).
Обратите внимание: экземпляр класса Сопел должен передавать клиенту (С овгоюе г) либо экземпляр класса Еюр1оуее (официант), либо себя самого, чтобы клиент (Соа1оюег) мог вызвать метод официанта (Еюр1оуее). Поэкспериментируйте с получившимися классами в интерактивной оболочке, импортируя класс Сопел и вызывая его метод огбег, чтобы запустить имитацию, а также метод гево11, чтобы проверить, что клиент (СовТоюе г) получил именно то, что заказывал. При желании можете добавить в файл с классами программный код самотестирования, используя прием с атрибутом паве из главы 21. Ватой имитации активность проявляет клиент (Совгозег); как бы вы изменили свои классы„чтобы инициатором взаимодействий между клиентом и официантом был официант (Еюр1оуее)? 8.