Методическая разработка урока
Элективный курс: Введение в объектно-ориентированное программирование на Python
Уровень: Программирование для начинающих
До этого мы говорили только о классах и объектах, которые создает программист (пользовательские классы). Однако Python настолько объектно-ориентированный язык, что в нем любые строка, число, список и др. являются по сути объектами, принадлежащими встроенным классам (типам данных): строкам, числам и др. Т. е. типы данных — это встроенные классы, а любые данные — это объекты.
Объектно-ориентированное программирование подразумевает не только наличие объектов, но и их взаимодействие между собой. Поэтому важно, чтобы к объектам разных классов можно было применить одну и туже операцию (например, сложение).
Для пользовательских классов предусмотрены специальные методы, позволяющие объектам данных классов участвовать в таких привычных операциях как сложение, вычитание, умножение, деление (+ - * /), а также во многих других. Другими словами, смысл (то, что он делает) знака + (или любого другого оператора) зависит от того, к каким объектам он применяется. Это называется перегрузкой операторов. В классах перегруженные операторы описываются с помощью специальных зарезервированных методов, которые в начале и в конце имеют по два знака подчеркивания. В уроке рассматриваются лишь некоторые из них. Кроме того, ранее был уже рассмотрен один такой метод — конструктор __init__, который автоматически вызывается при создании объектов класса.
Рассмотрим пример перегрузки операторов.
class Newclass:
def __init__(self, base):
self.base = base
def __add__(self, a):
self.base = self.base + a
def __str__(self):
return "%s !!! " % self.base
a = Newclass(10)
a + 20
print (a)
b = Newclass("yes")
b + "terday"
print (b)
c = Newclass([2,6,3])
c + [7, 1]
print (c)
В данном примере используется два метода (исключая __init__) перегрузки операторов: __add__ и __str__. Метод __add__ вызывается в том случае, когда объект данного класса участвует в операции сложения (для чисел), конкатенации (для строк) и объединения (для списков). Метод __str__ вызывается, когда объект передается в качестве аргумента встроенной функции print (на самом деле не только ей) и представляет данные в виде строки.
Результат работы скрипта представленного выше будет таким:
30 !!!
yesterday !!!
[2, 6, 3, 7, 1] !!!
Задание. Спешите пример, посмотрите как он работает. Дополните класс методами __mul__ (вызывается при использовании объекта в операциях умножения) и __sub__ (вычитание). Вызовите данные методы с помощью соответствующих операций с объектами. Для каких объектов невозможно использовать метод __sub__?
__call__ - перегрузка вызова функции
Метод __call__ автоматически вызывается, когда к объекту обращаются как к функции. Например, здесь во второй строке произойдет вызов метода __call__ некогоКласса:
объект = некийКласс()
объект([возможные аргументы])
Другими словами, метод __call__ позволяет объектам вести себя как функции.
Пример:
class Changeable:
def __init__(self, color):
self.color = color
def __call__(self, newcolor):
self.color = newcolor
def __str__(self):
return "%s" % self.color
canvas = Changeable("green")
frame = Changeable("blue")
canvas("red")
frame("yellow")
print (canvas, frame)
В этом примере с помощью конструктора класса при создании объектов устанавливается их цвет. Если требуется его поменять, то достаточно обратиться к объекту как к функции и в качестве аргумента передать новый цвет. Такой обращение автоматически вызовет метод __call__ (который, в данном случае, изменит атрибут color объекта).
Задание. Создайте класс с методом __call__, принимающим два параметра и производящим над ними те или иные математические операции. Создайте несколько объектов класса и, затем, обратитесь к ним как к функциям.
Рассмотренные в этом уроке методы перегрузки операторов лишь малая часть из существующих. Фактически все, что можно делать со встроенными типами (числами, словарями и др.), можно реализовать и для пользовательских типов (классов). Можно сказать, что перегрузка операторов обеспечивает единый интерфейс для встроенных и пользовательских типов (классов). Так, в первом примере можно видеть как "складываются" объект-число и объект класса Newclass.