Доброго времени суток, читатели, зрители моего канала programmer's notes.
Теперь в Дзен есть Подборки. Данная статья относится к подборке
Приложение к видео
Нюансы наследования в Python
Класса object
В видеоуроке, приложением к которому является данный текст, по сути, проходит красной линией одна мысль: в Python любой класс является чьим-то наследником, т.е. у него всегда есть родитель.
Так вот, даже если вы в Python пишите class class1: — это не означает, что этот класс сам по себе. Это означает, что он создается как наследник системного класса языка Python: object. Т.е. любой класс в вашей программе является наследником, производным классом. И правильнее было бы писать class class1(object), хотя так уже пишут далеко не все и далеко не всегда.
Результат выполнения программы
Перед созданием объекта
Конструктор class1
При этом строка
ins = super().__new__(my)
означает, что мы обращаемся к классу-родителю, базовому классу, который создает на основе имени передаваемого класса объект, который и возвращается (точнее всё-таки указатель на него). Как создаётся этот объект - мы не знаем, это всё скрыто в исполняемом коде интерпретатора Python. Да нам это и не нужно, но нужно понимать. А если, мы не будем переопределять __new__, то он автоматически будет запущен у базового класса с именем нужного класса, и объект будет создан. Так что обычно, переопределять __new__ в своем классе не стоит. Мы это, в данном случае, делаем, только ради понимания.
Наследование от стандартных типов (классов)
Я еще в базом курсе подчеркивал, что в Python всё является объектами. Другими словами int, str, list и т.д. являются классами. И когда мы пишем a = 5, например, мы создаем экземпляр класса int, при этом равносильно было бы написать a = int(5).
Ниже представлена программа, где класс является наследником класса int.
Результат выполнения программы
10
18
5
Следует сделать несколько пояснений к программе
1. Поскольку int является неизменяемым типом, то для указания количества параметров при наследовании (в данном случае 1), необходимо переопределять __new__, где определяется нужное количество параметров. Напомню, что переменную неизменяемого типа можно "изменить" только создав новое значение для нее. В нашем случае, кроме обязательного cls (имя класса), мы добавили ещё один параметр.
2. При наследовании от стандартных типов, наследуются методы, но не операторы. Для использования оператора "+" мы использовали магические методы __add__ и __radd__.
3. Метод bit_length() определен для типа int и наследуется нашим классом. При необходимости его можно переопределить.
Следующий пример аналогичен предыдущему, но реализован для изменяемого типа. Мы взяли тип list.
Поскольку мы имеем дело с изменяемым типом, то определять свой __new__ совсем не обязательно.
Результат выполнения программы
1
2
Опять же, методы list наследуются, а операторы приходится определять самим с помощью магических методов. Мы реализовали оператор чтения элемента объекта по индексу (метод __getitem__).
Всего наилучшего. Оставляйте свои комментарии, не забывайте про лайки и подписывайтесь на мой канал programmer's notes.