0 знаков
64. Основы написания классов в Python
Кратко- В этом уроке мы разберемся с оператором
classи его преимуществами на основе простых примеров.- Объект класса - это "фабрика" для производства экземпляров.
- Перегрузка операторов позволяет изменить поведение оператора в зависимости от типа объекта.
- Наследование классов - это поиск атрибутов среди связанных объектов.
- Атрибуты объекта реализуются как словари, связанные с другими словарями.
- Каждый экземпляр имеет ссылку на свой класс и кортеж ссылок из суперклассов.
- Динамическое создание атрибута для класса возможно.
Введение
В предыдущем уроке мы поверхностно пробежались по основным отличительным особенностям классов от ранее изучаемых средств. В этом уроке на основе простых примеров будем разбираться более детально с оператором 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() # => Иван В этом уроке мы разграничили понятия экземпляр и объект класса, немного углубились в перегрузку операторов и начали вникать в наследование классов. Конечно, о многом не было сказано и какие-то вещи остались в тени, но вы не беспокойтесь, в последующих уроках мы будем раскладывать все по полочкам и углубляться в каждую тему. В следующем уроке познакомимся с написание конструктора класса, узнаем о инкапсуляции и поработаем с базой данных (вернее, с ее аналогом на основе текстового файла).
Тест
Похожие уроки Codebra
Подписывайся на наш Telegram-канал!
Новости, полезный материал,
программирование и ИБ
Подписывайся на наш Telegram-канал!
Новости, полезный материал,
программирование и ИБ