Теория урока

73. Основы написания классов в Python

Оглавление урока

Введение

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

Объект класса или экземпляров? Под объектом класса понимается сама «фабрика» для производства экземпляров. Вспомним класс Wheel из предыдущего урока:

Пример
class Wheel:
pressure = 2.0

def forward_rotation(self):
pass

def backwards_rotation(self):
pass

И его использование:

Пример
fl = Wheel()

Выполнение оператора class создает объект класса и присваивает ему имя Wheel, который мы в дальнейшем используем в роли «фабрики» для экземпляров.

Объект fl является экземпляром. Таких экземпляров может быть бесчисленное множество.

Перегрузка операторов

В предыдущем уроке мы упоминали про перегрузку операторов, когда разбирались с конструктором класса. Создадим простой класс, в котором будет определен конструктор для инициализации атрибута data.

Пример
class SimpleSum:
data = 0

def __init__(self, d):
self.data = d

num = SimpleSum(10)

print(num.data) # => 10
print(num + 10) # => ???

Мы создали экземпляр num, и вывели значение атрибута data. Но что произойдет, если мы попробуем прибавить к num число 10? Будет поднято исключение TypeError (про исключения мы говорили в уроке «Обработка исключений (try/except) в Python»).

Оператор «+» можно перегрузить точно также, как и конструктор класса __init__. Метод __add__ будет выполнятся, если экземпляр класса SimpleSum будет встречен в выражении +.

Пример
class SimpleSum:
data = 0

def __init__(self, d):
self.data = d

def __add__(self, second):
self.data = self.data + second

num = SimpleSum(10)

print(num.data) # => 10
num + 10
print(num.data) # => 20

Таким образом, мы перегрузили оператор «+» и теперь Python понимает, что не нужно пытаться прибавить к объекту класса SimpleSum простое число, а следует прибавить к атрибуту data, этого экземпляра и сохранить результат в нем же. К перегрузке операторов мы еще вернемся.

Другие атрибуты класса и снова про наследование

Модель наследования очень проста, она сводится к поиску атрибутов среди связанных объектов. Давайте создадим пустой класс:

Пример
class Empty:
pass

С оператором pass вы знакомы из урока «Операторы break, continue и pass в Python». С большим успехом мы можем присоединить к нему новые атрибуты, например:

Пример
Empty.name = "Иван"
print(Empty.name)

Теперь посмотрим на модель наследования в действии. Создадим два экземпляра из объекта Empty.

Пример
Empty.name = "Иван"

x = Empty()
y = Empty()

print(x.name) # => Иван
print(y.name) # => Иван

Фактически, экземпляры не имеют атрибутов – они берут их из объекта класса. В следующем примере экземпляр x по-прежнему наследует атрибут name, но мы присвоили ему другое значение:

Пример
x.name = "Петр"

print(x.name) # => Петр
print(y.name) # => Иван

Как мы будем говорить в дальнейшем, атрибуты объекта реализуются как словари, которые связаны с другими словарями:

Пример
Empty.__dict__.keys() # => dict_keys(['__module__', '__dict__', '__weakref__', '__doc__', 'name'])

x.__dict__.keys() # => dict_keys(['name'])

Возвращаясь к поиску в иерархии наследования, каждый экземпляр имеет ссылку на свой класс, которую можно получить следующим образом:

Пример
x.__class__ # => <class '__main__.Empty'>

Также можно получить кортеж ссылок из суперклассов для объекта, например:

Пример
print(Empty.__bases__) # => (<class 'object'>,)

Наш класс Empty наследуется только от общего суперкласса object, являющимся родителем для всех и о котором будем говорить в дальнейшем.

Ранее было показано, как динамически создать атрибут для класса. Теперь попробуем добавить метод в наш пустой класс Empty. Напомню про отличие функции от метода класса, в последнем есть ссылка на сам объект (self). Учтем это при написании функции:

Пример
def print_name(obj):
print(obj.name)

Empty.name = "Иван"

print_name(Empty) # => Иван

Теперь сделаем функцию print_name() методом класса Empty с именем method_print().

Пример
Empty.name = "Иван"
Empty.method_print = print_name

x = Empty()

x.method_print() # => Иван

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

ПРОЧИТАНО
Следующий урок

Похожие уроки и записи блога

Продолжаем написание классов в PythonЗнакомство с Python
Основы объектно-ориентированного программирования (ООП) в PythonЗнакомство с Python
Обработка исключений (try/except) в PythonЗнакомство с Python
Написание модулей в PythonЗнакомство с Python
Типы данных в PythonЗнакомство с Python
Функциональное программирование: map, filter и reduceЗнакомство с Python
Работа с файлами в Python Знакомство с Python
Еще о возможностях модулей в Python Знакомство с Python
Аргументы и параметры функций, операторы * и ** в PythonЗнакомство с Python
<
×
>
Впервые на сайте Codebra?

Извините за это всплывающее окно, меня они тоже раздражают.

Образовательный ресурс codebra.ru полностью посвящен программированию. Все курсы и уроки находятся на главной странице. Ради интереса можете посмотреть на содержимое курсов по Python, HTML и CSS, JavaScript, C++ и другие, размещенные на главной странице.

Если что-то не нашли, то воспользуйтесь поиском по сайту, который находится на главной странице в самом верху.

Удачи в обучении!

Закрыть окно