Главная страница
Навигация по странице:

  • Закрепление пройденного Контрольные вопросы

  • Классы генерируют множество экземпляров объектов

  • Объекты классов реализуют поведение по умолчанию

  • FirstClass наследует – setdata – display Y – data X – data Рис. 23.1.

  • Классы адаптируются посредством наследования

  • Математический анализ. 3е издание


    Скачать 4.86 Mb.
    Название3е издание
    АнкорМатематический анализ
    Дата04.02.2022
    Размер4.86 Mb.
    Формат файлаpdf
    Имя файлаpython_01.pdf
    ТипДокументы
    #351981
    страница70 из 98
    1   ...   66   67   68   69   70   71   72   73   ...   98
    575
    В заключение
    В этой главе мы в общих чертах рассмотрели ООП и классы, получив представление о них, прежде чем углубиться в детали синтаксиса. Как мы узнали, основу ООП составляет поиск атрибутов в дереве связан
    ных объектов; мы называем его поиском в дереве наследования. Объек
    ты в нижней части дерева наследуют атрибуты объектов, расположен
    ных в дереве выше, – эта особенность позволяет создавать программы за счет адаптации программного кода, а не за счет его изменения или создания нового кода. При грамотном использовании эта модель про
    граммирования может привести к существенному сокращению време
    ни, необходимого на разработку.
    В следующей главе мы приступим к рассмотрению подробностей,
    стоящих за общей картиной, рассмотренной здесь. Мы начнем углуб
    ляться в изучение классов, однако не стоит забывать, что объектно
    ориентированная модель в языке Python очень проста – как я уже за
    метил, она, по сути, сводится к поиску атрибутов в деревьях объектов.
    Прежде чем двинуться дальше, ответьте на контрольные вопросы, что
    бы освежить в памяти все то, о чем рассказывалось здесь.
    Закрепление пройденного
    Контрольные вопросы
    1. Каково основное назначение ООП в языке Python?
    2. Где выполняется поиск унаследованных атрибутов?
    3. В чем разница между объектом класса и объектом экземпляра?
    4. В чем состоит особенность первого аргумента в методах классов?
    5. Для чего служит метод __init__?
    6. Как создать экземпляр класса?
    7. Как создать класс?
    8. Как определяются суперклассы для класса?
    Ответы
    1. Основное назначение ООП состоит в том, чтобы обеспечить много
    кратное использование программного кода, – программный код разлагается на составляющие, чтобы снизить его избыточность,
    и при создании новых программ выполняется адаптация имеюще
    гося программного кода, а не изменение существующего или созда
    ние нового кода.
    2. Поиск унаследованных атрибутов выполняется сначала в объекте экземпляра, затем в классе, из которого был создан экземпляр, за
    тем во всех суперклассах, в направлении снизу вверх и слева напра

    576
    Глава 22. ООП: общая картина во в дереве объектов (по умолчанию). Как только будет найдено пер
    вое вхождение атрибута, поиск прекращается. Поскольку резуль
    татом поиска является самая нижняя версия имени из имеющихся в дереве, иерархия классов естественным образом поддерживает возможность адаптации за счет создания подклассов.
    3. И классы, и экземпляры – это пространства имен (пакеты перемен
    ных, которые играют роль атрибутов). Главное различие между ни
    ми состоит в том, что классы представляют собой своего рода фабри
    ки, позволяющие производить множество экземпляров. Кроме того,
    классы поддерживают методы перегрузки операторов, которые на
    следуются экземплярами, а функции, вложенные в классы, интер
    претируются как специальные методы обработки экземпляров.
    4. Первый аргумент в методах классов играет особую роль, так как че
    рез него всегда передается ссылка на объект экземпляра, который подразумевается при вызове метода. Согласно общепринятым со
    глашениям он обычно называется self. Так как по умолчанию ме
    тоды всегда принимают этот подразумеваемый объект, мы говорим,
    что они «объектноориентированные», то есть предназначенные для обработки или изменения объектов.
    5. Если метод __init__ присутствует в классе или наследуется им, ин
    терпретатор автоматически будет вызывать его при создании каж
    дого экземпляра этого класса. Этот метод также называют конст
    руктором – он неявно получает новый экземпляр, а также все аргу
    менты, которые были указаны при вызове имени класса. Кроме то
    го, он является типичным представителем методов перегрузки операторов. В отсутствии метода __init__ экземпляры начинают свое существование как пустые пространства имен.
    6. Экземпляр класса создается вызовом имени класса, как если бы это была функция – любые аргументы в вызове будут переданы конст
    руктору __init__, как второй и следующие аргументы. Новый эк
    земпляр запоминает, из какого класса он был создан, благодаря че
    му обеспечивается наследование.
    7. Класс создается с помощью инструкции class, так же как определе
    ния функций. Эти инструкции обычно выполняются во время им
    портирования файла вмещающего модуля (подробнее об этом рас
    сказывается в следующей главе).
    8. Суперклассы для заданного класса определяются в виде списка в круглых скобках в инструкции class после имени нового класса.
    Порядок следования суперклассов в списке определяет порядок по
    иска в дереве наследования.

    23
    Основы программирования классов
    Теперь, когда мы поговорили об ООП в общем, настало время посмот
    реть, как это выглядит в фактическом программном коде. В этой и сле
    дующей главах подробно будет рассказываться о синтаксисе, который составляет основу модели классов в языке Python.
    Если ранее вам не приходилось сталкиваться с ООП, будет сложно сра
    зу усвоить все сведения о классах. Чтобы облегчить освоение програм
    мирования классов, мы начнем наше детальное исследование ООП
    с того, что рассмотрим в этой главе несколько простых классов в дей
    ствии. Классы в языке Python в самой простой их форме легко понять,
    а детали будут рассмотрены подробнее в следующих главах.
    Классы обладают тремя основными отличительными особенностями.
    На самом простом уровне они представляют собой всего лишь про
    странства имен, во многом похожие на модули, которые мы изучали в пятой части книги. Но, в отличие от модулей, классы также поддер
    живают создание множества объектов, реализуют наследуемое про
    странство имен и перегрузку операторов. Начнем наше путешествие с инструкции class и исследуем каждую из этих трех особенностей.
    Классы генерируют множество
    экземпляров объектов
    Чтобы понять, каким образом обеспечивается возможность создания множества объектов, для начала нужно понять, что в объектноориен
    тированной модели языка Python существует две разновидности объек
    тов: объекты классов и объекты экземпляров. Объекты классов реали
    зуют поведение по умолчанию и играют роль фабрик по производству объектов экземпляров. Объекты экземпляров – это настоящие объек
    ты, обрабатываемые программой, – каждый представляет собой само
    стоятельное пространство имен, но наследует имена (то есть автомати

    578
    Глава 23. Основы программирования классов чески имеет доступ к ним) класса, из которого он был создан. Объекты классов создаются инструкциями, а объекты экземпляров – вызова
    ми. Каждый раз, когда вы вызываете класс, вы получаете новый эк
    земпляр этого класса.
    Эта объектная концепция существенно отличается от любых других программных конструкций, которые мы видели до сих пор в этой кни
    ге. В действительности, классы – это фабрики, способные производить множество экземпляров. В противоположность этому каждый модуль в программе может присутствовать в единственном экземпляре (фак
    тически это одна из причин, почему необходимо использовать функ
    цию reload для обновления объекта модуля, чтобы отразить внесенные в модуль изменения).
    Ниже приводится краткий обзор основных особенностей ООП в языке
    Python. Как вы увидите, классы в языке Python сочетают в себе черты,
    напоминающие функции и модули, но они совершенно не похожи на классы в других языках программирования.
    Объекты классов реализуют поведение по умолчанию
    Когда выполняется инструкция class, она создает объект класса. Ни
    же приводятся несколько основных отличительных характеристик классов в языке Python.

    Инструкция class создает объект класса и присваивает ему имя.
    Так же как и инструкция def, инструкция class является выполняе+
    мой
    инструкцией. Когда она выполняется, она создает новый объ
    ект класса и присваивает его имени, указанному в заголовке инст
    рукции class. Кроме того, как и инструкции def, инструкции class обычно выполняются при первом импортировании содержащих их файлов.

    Операции присваивания внутри инструкции class создают атрибу!
    ты класса. Так же как и в модулях, инструкции присваивания на верхнем уровне внутри инструкции class (не вложенные в инструк
    ции def) создают атрибуты объекта класса. С технической точки зре
    ния инструкция class преобразует свою область видимости в про
    странство имен атрибутов объекта класса, так же, как глобальная область видимости модуля преобразуется в его пространство имен.
    После выполнения инструкции class атрибуты класса становятся доступны по их составным (полным) именам: object.name.

    Атрибуты класса описывают состояние объекта и его поведение.
    Атрибуты объекта класса хранят информацию о состоянии и опи
    сывают поведение, которым обладают все экземпляры класса, – ин
    струкции def, вложенные в инструкцию class, создают методы, ко
    торые обрабатывают экземпляры.

    Классы генерируют множество экземпляров объектов
    579
    Объекты экземпляров – это конкретные элементы
    Когда вызывается объект класса, возвращается объект экземпляра.
    Ниже приводятся несколько отличительных характеристик экземп
    ляров классов:

    Вызов объекта класса как функции создает новый объект экземп!
    ляра. Всякий раз, когда вызывается класс, создается и возвращает
    ся новый объект экземпляра. Экземпляры представляют собой кон
    кретные элементы данных в вашей программе.

    Каждый объект экземпляра наследует атрибуты класса и приобре!
    тает свое собственное пространство имен. Объекты экземпляров создаются из классов и представляют собой новые пространства имен; они первоначально пустые, но наследуют атрибуты классов,
    из которых были созданы.

    Операции присваивания значений атрибутам через ссылку self
    в методах создают атрибуты в каждом отдельном экземпляре. Ме
    тоды класса получают в первом аргументе (с именем self в соответ
    ствии с соглашениями) ссылки на обрабатываемый объект экземп
    ляра – присваивание атрибутам через ссылку self создает или изме
    няет данные экземпляра, а не класса.
    Первый пример
    Обратимся к первому примеру, демонстрирующему работу этих идей на практике. Для начала определим класс с именем FirstClass, выполнив инструкцию class в интерактивной оболочке интерпретатора Python:
    >>> class FirstClass: # Определить объект класса
    ... def setdata(self, value): # Определить методы класса
    ... self.data = value # self – это экземпляр
    ... def display(self):
    ... print self.data # self.data: данные экземпляров
    Здесь мы работаем в интерактивной оболочке, но обычно такие инст
    рукции выполняются во время импортирования вмещающего файла модуля. Подобно функциям, создаваемым с помощью инструкции def,
    классы не существуют, пока интерпретатор Python не достигнет этих инструкций и не выполнит их.
    Как и все составные инструкции, инструкция class начинается со строки заголовка, содержащей имя класса, за которой следует тело класса из одной или более вложенных инструкций (обычно) с отступа
    ми. Здесь вложенными инструкциями являются инструкции def – они определяют функции, реализующие поведение класса. Как мы уже знаем, инструкции def в действительности являются операциями при
    сваивания – в данном случае они присваивают объекты функций име
    нам setdata и display в области видимости инструкции class и тем са
    мым создают атрибуты, присоединяемые к классу: FirstClass.setdata

    580
    Глава 23. Основы программирования классов и FirstClass.display. Фактически любое имя, которому присваивается значение на верхнем уровне во вложенном блоке класса, становится атрибутом этого класса.
    Функции внутри классов обычно называются методами. Это обычные инструкции def, и для них верно все то, что мы уже знаем о функциях
    (они могут иметь аргументы со значениями по умолчанию, возвращать значения и т. д.). Но в первом аргументе методы автоматически получа
    ют подразумеваемый объект экземпляра – контекст вызова метода. Нам необходимо создать пару экземпляров, чтобы понять, как это делается:
    >>> x = FirstClass() # Создаются два экземпляра
    >>> y = FirstClass() # Каждый является отдельным пространством имен
    Вызывая
    класс таким способом (обратите внимание на круглые скоб
    ки), мы создаем объекты экземпляров, которые являются всего лишь пространствами имен и обладают доступом к атрибутам класса. Собст
    венно говоря, к настоящему моменту у нас имеется три объекта – два экземпляра и один класс. В действительности у нас имеется три свя
    занных пространства имен, как показано на рис. 23.1. В терминах
    ООП мы говорим, что x «наследует» классу FirstClass, как и y.
    Изначально оба экземпляра пустые, но они связаны с классом, из ко
    торого были созданы. Если через имя экземпляра обратиться к атрибу
    ту объекта класса, то в результате поиска по дереву наследования ин
    терпретатор вернет значение атрибута класса (при условии, что в эк
    земпляре отсутствует одноименный атрибут):
    >>> x.setdata("King Arthur") # Вызов метода: self – это x
    >>> y.setdata(3.14159) # Эквивалентно: FirstClass.setdata(y, 3.14159)
    Ни x, ни y не имеют собственного атрибута setdata, поэтому, чтобы оты
    скать его, интерпретатор следует по ссылке от экземпляра к классу.
    В этом заключается суть наследования в языке Python: механизм на
    следования привлекается в момент разрешения имени атрибута, и вся
    наследует
    FirstClass
    наследует
    – setdata
    – display
    Y
    – data
    X
    – data
    Рис. 23.1. Экземпляры и классы – это связанные между собой объекты
    пространств имен в дереве наследования классов, внутри которого
    выполняется поиск. Здесь атрибут «data» обнаруживается в экземплярах,
    а «setdata» и «display» – в классе, расположенном выше их

    Классы генерируют множество экземпляров объектов
    581
    его работа заключается лишь в поиске имен в связанных объектах (на
    пример, следуя по ссылкам «наследует», как показано на рис. 23.1).
    В функции setdata внутри класса FirstClass значение аргумента запи
    сывается в self.data. Имя self внутри метода – имя самого первого ар
    гумента, в соответствии с общепринятыми соглашениями, – автомати
    чески ссылается на обрабатываемый экземпляр (x или y), поэтому опе
    рация присваивания сохраняет значения в пространстве имен экземп
    ляра, а не класса (так создаются имена data, показанные на рис. 23.1).
    Поскольку классы способны генерировать множество экземпляров, ме
    тоды должны использовать аргумент self, чтобы получить доступ к об
    рабатываемому экземпляру. Когда мы вызываем метод класса display,
    чтобы вывести значения атрибутов self.data, мы видим, что для каждо
    го экземпляра они разные; с другой стороны, имя display само по себе одинаковое в x и y, так как оно пришло (унаследовано) из класса:
    >>> x.display() # В каждом экземпляре свое значение self.data
    King Arthur
    >>> y.display()
    3.14159
    Обратите внимание, что в атрибутах data экземпляров мы сохранили объекты различных типов (строку и число с плавающей точкой). Как и повсюду в языке Python, атрибуты экземпляров (иногда называются
    членами
    ) никак не объявляются – они появляются, как только будет выполнена первая операция присваивания, точно так же, как и в слу
    чае с переменными. Фактически, если вызвать метод display до вызова метода setdata, будет получено сообщение об ошибке обращения к не
    определенному имени – атрибут с именем data не существует в памяти,
    пока ему не будет присвоено какоелибо значение в методе setdata.
    Еще один способ, дающий возможность оценить, насколько динамич
    на эта модель, позволяет изменять атрибуты экземпляров в самом классе, выполняя присваивание как с помощью аргумента self внутри методов, так и за пределами класса, когда экземпляр явно участвует в операции присваивания:
    >>> x.data = "New value" # Можно получать/записывать значения атрибутов
    >>> x.display() # И за пределами класса тоже
    New value
    Хотя это и нечасто применяется, тем не менее существует возмож
    ность создания новых атрибутов в пространстве имен экземпляра,
    присваивая значения именам за пределами методов класса:
    >>> x.anothername = "spam" # Здесь также можно создавать новые атрибуты
    Эта операция присоединит новый атрибут с именем anothername, кото
    рый затем сможет использоваться любыми методами класса в объекте экземпляра x. Обычно классы создают все атрибуты экземпляров за счет присваивания значений аргументу self, но это не обязательно –

    582
    Глава 23. Основы программирования классов программы могут получать, изменять или создавать атрибуты в лю
    бых объектах, к которым они имеют доступ.
    Классы адаптируются посредством наследования
    Помимо роли фабрик по созданию объектов экземпляров, классы так
    же позволяют нам вносить изменения за счет введения новых компо
    нентов (которые называются подклассами), а не за счет изменения су
    ществующего программного кода. Объекты экземпляров, созданные из класса, наследуют атрибуты класса. В языке Python классы также могут наследовать другие классы, что открывает дверь к созданию ие+
    рархий
    классов, поведение которых специализируется за счет переоп
    ределения существующих атрибутов ниже в иерархии. Здесь также нет никакого сходства с модулями: их атрибуты находятся в едином плоском пространстве имен.
    В языке Python экземпляры наследуют классам, а классы наследуют суперклассам. Ниже приводятся основные идеи, лежащие в основе ме
    ханизма наследования атрибутов:

    Суперклассы перечисляются в круглых скобках в заголовке инст!
    рукции class. Чтобы унаследовать атрибуты другого класса, доста
    точно указать этот класс в круглых скобках в заголовке инструкции class
    . Класс, который наследует, называется подклассом, а класс,
    которому наследуют, называется его суперклассом.
    1   ...   66   67   68   69   70   71   72   73   ...   98


    написать администратору сайта