Объектная модель Python
ООП: Поддержка в ЯП объектного проектирования. Статья на Википедии внезапно стала более вменяемой, интересной, но хуже читаемой: Объектно-ориентированное_программирование
Абстрагирование (общее/частное). Примеры: класс/экземпляр класса, базовый класс/производный класс и т. п. (Python: +метакласс)
Инкапсуляция: минимализация необходимого информационного пространства; часто — за счёт создания иерархии пространств имён (большинство языков: размещение в одном компоненте данных и методов, которые с ними работают)
- не смешивать с сокрытием
Наследование: повторное использование свойств объектов с описанием различий
Полиморфизм (а вот эту статью на Википедии не стоит читать на полном серьёзе): возможность для одного и того же кода обрабатывать данные разных типов (Python: duck typing!)
Абстрагирование
- Класс / экземпляр
- класс — конструктор экземпляров
- видимость полей
- Метакласс / класс (потом!)
- Метакласс — конструктор классов
- ...
Перегрузка операций
(Для тех, кто всё-таки прочитал WP-статью про полиморфизм: в Питоне за полиморфизм отвечает duck typing, а не это!)
Операций нет, а есть методы; операции — это
- вызов метода, или
- логика вызовов нескольких методов
Базовые функции
__init__() / __del__() (Note: del x doesn’t directly call x.__del__())
__str__(),__repr__(),__bytes__() — str(x)
__bool__(), __len__() — пустой ли?
__dict__(), __getattr__() / __getattribute__() / __setattr__() / __delattr__() / __dir__() — «.» и около
сравнения: __lt__(self, other), __le__(self, other), __eq__(self, other), __ne__(self, other), __gt__(self, other), __ge__(self, other)
Достаточно __lt__() и __eq__() (см. @functools.total_ordering)
Последовательности и прочие хранилища
__getitem__() / __setitem__() / __delitem__()/ __missing__()
__iter__()
__reversed__() или len() + getitem() — reversed(x)
__contains__() — a in x
Числа
Базовые операции (типа __add__()), в т. ч. несуществующая @ (__matmul__())
Инкрементальные операции типа += (__iadd__())
Правые операции (__radd__()), их происхождение и протокол применения
"qwe"*3 vs. 3*"qwe" vs. "qwe".__mul__(3) vs. 3.__mul__("qwe") vs. "qwe".__rmul__(3)
Property
Реализованы с помощью дескрипторов (см. след. лекцию)
- Это декоратор вокруг протокола дескрипторов
- Модель
Декораторы: @property (это getter) / @setter / @deleter:
см. пример
Д/З
Прочитать про классы в tutorial; про «волшебные методы» например, тут
Прочитать про ограничения на перегрузку спецметодов в справочнике
EJudge: DahDit 'Морзянка'
Написать класс morse("строка"), экземпляр которого переводит арифметические выражения в морзянку! Параметр «строка» бывает разных видов, более подробно описан в подсказках, желающие могут догадаться о его компонентах по примеру (пример почти полный). «+» — точка, «-» — тире, «~» — промежуток между буквами (бывает только между буквами и только один, проверять не надо).
1 print(-+morse()) 2 print(-++~+-+morse()) 3 print(--+~-~-++~+++-morse()) 4 print(--+~-~-++~+++-morse(".-")) 5 print(--+~-~-++~+++-morse("..-")) 6 print(--+~-~-++~+++-morse("..-|")) 7 print(--+~-~-++~+++-morse("dot DOT dash")) 8 print(--+~-~-++~+++-morse("ai aui oi ")) 9 print(--+~-~-++~+++-morse("dot dot dash ///"))
dah dit. dah di dit, di dah dit. dah dah dit, dah, dah di dit, di di di dah. --. - -.. ...- --. - -.. ...- --. - -.. ...-| dash dash DOT, dash, dash dot DOT, dot dot dot dash. oi oi aui, oi, oi ai aui, ai ai ai oi dash dash dot, dash, dash dot dot, dot dot dot dash///
EJudge: CyberSausage 'Киберколбаса'
Написать класс sausage, имитирующий киберколбасу. Киберколбаса может быть проинициализирована нулём значений (создаётся колбаса по умолчанию), одним (фарш) и двумя (фарш и объём). Длина целого батона киберколбасы 12 символов фарша и 2 оболочки. Колбаса единичного объёма — это один полный батон, более, чем единичного — это несколько батонов (последний, возможно, неполон). Неполный батон заканчивается срезом. Киберколбаса поддерживает операции умножения и деления на целое число, а также сложения и вычитания с другой киберколбасой (фарш результата совпадает с фаршем первого операнда). Если объём киберколбасы нулевой, батон считается пустым.
/------------\ |pork!pork!po| |pork!pork!po| |pork!pork!po| \------------/ /----------| |HAMHAMHAMH| |HAMHAMHAMH| |HAMHAMHAMH| \----------| /------------\/---| |SPAM.SPAM.SP||SPA| |SPAM.SPAM.SP||SPA| |SPAM.SPAM.SP||SPA| \------------/\---| /------------\/------------\/------------\/-| |pork!pork!po||pork!pork!po||pork!pork!po||p| |pork!pork!po||pork!pork!po||pork!pork!po||p| |pork!pork!po||pork!pork!po||pork!pork!po||p| \------------/\------------/\------------/\-| /------------\/--------| |HAMHAMHAMHAM||HAMHAMHA| |HAMHAMHAMHAM||HAMHAMHA| |HAMHAMHAMHAM||HAMHAMHA| \------------/\--------| /------------\ |SPAM.SPAM.SP| |SPAM.SPAM.SP| |SPAM.SPAM.SP| \------------/ /| || || || \| True /| || || || \| True
EJudge: SelfCount 'Сколько экземпляров'
Написать класс WeAre, объекты которого содержат поле count, содержащее количество существующих экземпляров этого класса. Игнорировать попытки изменить значение этого поля вручную или удалить его.
1 3 3 3 2