Компьютерная математика II

Дисциплина для студентов 1-го курса специальности «Компьютерная математика и системный анализ» ММФ БГУ

Тема 8. Основы объектно-ориентированного программирования в Python

доц. Лаврова О.А., кафедра дифференциальных уравнений и системного анализа (ауд. 329)

апрель, 2023

Python поддерживает три парадигмы программирования:

Основными концециями объектно-ориентированной парадигмы являются понятия объекта и класса.

8.1 Понятия класса и экземпляра класса

Объект — это базовая сущность в Python для представления данных, обладающая определенным состоянием и поведением.

Класс — это способ описания множества однотипных объектов с одинаковыми свойствами и одинаковыми операциями для совершения действий над объектами этого множества.

Встроенные типы данных (int, float, complex, bool, str, tuple, list, dict, set) являются встроенными классами в Python.

Пользовательский класс определяет НОВЫЙ ТИП ДАННЫХ, который не является встроенным типом в Python, и используется для создания объектов НОВОГО ТИПА. Объекты, созданные на основе класса, называются экземплярами класса (class instance).

Объектно-ориентированная парадигма — это программирование с применением экземпляров пользовательских классов.

С точки зрения программирования, класс — это способ группирования переменных, созданных явными присваиваниями, и функций с целью дальнейшего многократного их использования посредством создания экземпляров класса.

Классы группируют внутри себя переменные и функции, которые после создания экземпляра этого класса, становятся атрибутами экземпляра.

Атрибуты — это имена/переменные, которые связаны с объектом и используются для получения информации об объекте, а также для совершения действий над этим объектом.

Функциональные атрибуты объекта называются методами.

Нефункциональные атрибуты объектов класса и экземпляров класса будем в дальнейшем называть атрибутами.

8.2 Оператор создания класса

Для создания класса используется оператор class.

Оператор class является составным оператором, тело которого состоит из операторов явного приcваивания = и операторов определения функций def.

Синтаксический шаблон оператора class:

class <NameOfClass>(...):        
    <atribute1> = ...
    ...
    <atributeN> = ...

    def <method1>(...):             
        ...
    ...
    def <methodM>(...):             
        ...

Рекомендовано начинать имя класса с буквы верхнего регистра.

При выполнении оператора class осуществляется выполнение операторов из тела класса, создание объекта класса и неявное присваивание объекта класса переменной <Имя_класса>.

Переменные и функции, определенные внутри оператора class на верхнем уровне, становятся атрибутами и методами созданного объекта класса

Атрибуты объекта класса можно изменять за пределами оператора class с использованием оператора присваивания

Атрибуты объекта класса можно создавать за пределами оператора class с использованием оператора присваивания для НОВОГО атрибута объекта класса

Просмотрим все атрибуты класса MyClass, которые не начинаются с символа подчеркивания

Строковый литерал строк документации записывается в атрибут __doc__ объекта класса при выполнении оператора class

С объектом класса в коде можно выполнить два действия: использовать атрибуты и методы объекта класса и создать экземпляры класса.

Для создания экземпляра класса необходимо обратиться к объекту класса как к функции

Объекты классов и объекты экземпляров классов являются объектами разных типов

Атрибуты и методы объекта класса становятся атрибутами и методами для КАЖДОГО экземпляра класса. Говорят, что атрибуты/методы класса наследуются всеми экземплярами, созданными на основе класса

Все экземпляры, созданные на основе класса, разделяют пространство имен этого класса. Это означает, что изменение значений атрибутов и методов объекта класса отражается на ВСЕХ экземплярах этого класса

Присваивание нового значения для атрибута класса через объект экземпляра класса создает новую одноименную переменную в собственном пространстве имен конкретного экземпляра класса. Изменение значения атрибута не отражается ни на объекте класса, ни на других экземплярах этого класса

С экземпляром класса в коде можно выполнить только одно действие: сослаться на атрибуты или методы, которые расположены в собственном пространстве имен экземпляра или которые унаследованы от класса.

8.3 Методы класса

Основным назначением методов класса является обработка экземпляров классов.

Для того, чтобы метод класса мог обрабатывать конкретный экземпляр класса, он/метод должен содержать специальный первый аргумент, который по соглашению называется self, для автоматической передачи методу класса экземпляра класса, на котором был вызван метод.

Аналогом self в Python является this в С++ и Java.

При вызове первый аргумент self заполняется автоматически для ссылки на экземпляр, на котором произведен вызов, для дальнейшей обработки экземпляра класса. Значения аргументов, перечисленные в круглых скобках при вызове метода, сопоставляются со вторым и последующими аргументам метода класса.

Аргумент self метода класса связывает метод класса с экземпляром класса, на котором осуществляется вызов этого метода. Так как на основании одного класса может быть создано несколько экземпляров этого класса, каждый экземпляр класса должен обрабатываться одним и тем же методом уникально и независимо от других экземпляров класса.

Вызов экземпляр.метод(аргументы) автоматически отображается на вызов метода класса класс.метод(экземпляр, аргументы), передавая экземпляр в первом аргументе унаследованной функции метод.

Объект метода класса для экземпляра класса, является не объектом функции, а объектом связанного метода. В объект связанного метода Python автоматически помещает экземпляр класса первым аргументом, связывая экземпляр класса и метод класса

Через атрибут __self__ объекта связанного метода можно получить доступ к экземпляру класса, на котором вызывается метод. Через атрибут __func__ объекта связанного метода можно получить доступ к объекту функции класса, который метод реализует.

Если действия над экземплярами класса реализуются при определении класса с помощью методов класса, то это называется концепцией инкапсуляции. Код для обработки экземпляров класса пишется только один раз в виде метода класса, метод класса наследуется экземплярами класса при их создании и может использоваться каждым экземпляром класса по необходимости.

8.4 Метод инициализации экземпляра класса

Для создания экземпляра класса прежде всего нужно создать соответствующий класс, используя оператор class <Имя_класса>(…). При выполнении оператора class будет создан объект класса и реализована ссылка переменной <Имя_класса> на этот объект класса.

Далее для создания экземпляра класса следует вызвать объект класса как функцию, указывая <Имя_класса> и аргументы вызова либо пустые круглые скобки.

Если при построении экземпляра класса необходимо инициализировать данные этого объекта, то оператор class должен содержать метод __init__ (не всегда так бывает).

Метод __init__ инициализирует экземпляр класса: он обязан передать значения аргументов при вызове метода атрибутам объекта.

При этом в операторе def метода __init__ первым аргументом должен быть указан специальный аргумент self.

При вызове метода инициализации экземпляра класса __init__ первый аргумент self автоматически становится ссылкой на объект созданного экземпляра. Значения аргументов, перечисленные в круглых скобках при вызове объекта класса как функции <Имя_класса>(<аргумент1>,...,<аргументN>), сопоставляются со вторым и последующими аргументам метода класса __init__(self, <аргумент1>,...,<аргументN>).

Присваивание атрибутам аргумента self создает атрибут экземпляра или изменяет значение существующего атрибута в экземпляре, но не в классе. Такие присваивания возможны только внутри методов классов.

Значения атрибутов для каждого экземпляра класса уникальные и не зависят от значений аналогичных атрибутов других экземпляров.

Анализируя код метода инициализации __init__, можно узнать имена атрибутов для экземпляров класса.

Экземпляры класса Complex будут иметь два атрибута r и i и один метод modulus, унаследованный от класса Complex