Наследование и другие свойства ООП
Долги за прошлую лекцию:
Пакеты: неудобная для online-объяснения тема, проще посмотреть в modules.html
Разбор (возможно, только по смыслу) задач SubModules и GuessSigns
Наследование
Простое: class B(A):
- Правила видимости полей, вызов «чужих» методов при необходимости
- пример
рекуррентный вызов базовый_класс.__init__(self) при инициализации
- пример
Порождение объектов (например, при __add__) при помощи self.__class__
Защита полей от случайного доступа с помощью «__» (a.__field в классе C превращается в a._C__field)
- Правила видимости полей, вызов «чужих» методов при необходимости
- Множественное
- старые классы: дерево
JT:
- техника объектного планирования с деревом классов
- «дешевизна» классов в python
Исключения как классы
См. classes.html
- Зачем исключениям иерархия
Старые и новые классы
Главная проблема старых классов: тип «class»
- (и другие: замкнутый граф наследования, спецметоды, …)
Новые классы: (Python2: class C(object):)
Просто «type» и объект этого типа
Ещё более гибкий:
объект.__new__(self_класс, …)
__getattribute__
__slots__ (общие поля всех объектов класса)
Дескрипторы (Raymond Hettinger растолковывает)
это такой тип поля, для которого перегружаются __get__(), __set__() и __delete__() (а при вызове обращаются обратно к классу)
синтаксический сахар (и сверх того!) относительно __getattribute__()
Множественное наследование: C3 MRO
super(класс) (Raymond Hettinger с восторгом раскрывает эту тему)
У меня от всего этого мозги закукливаются, for TrueЪ probgammers only -- FrBrGeorge 2014-11-28 15:35:41
Ещё ссылки
- Статьи на Хабре:
Про дескрипторыперевод статьи Раймонда, важное дополнение;
Вообще (тысячи их)
Декораторы
Декоратор — это функция, возвращающая функцию. Нужна для красоты.
- Пример, где нужна красота: метод класса (unbound) vs. метод объекта
И вот: @property, @classmethod, @staticmethod
Две статьи на Хабре: Понимаем декораторы и Понимаем параметрические декораторы
Д/З
- Прочитать:
Раздел Data model (весь, можно несколько раз)
- Всё по ссылкам выше
(SelfishTuple) Выворачиваемый кортеж
Определить класс MTuple, проксирующий тип tuple, с добавлением в него единственной операции — унарного минуса (операция возвращает MTuple с элементами в обратном порядке). Прочие операции также должны возвращать MTuple вместо tuple.
c=mod.MTuple(range(10)) print -(-c[2:6]+c[-1:2:-2]) print -c[7:9]+("Bdyshch","Bdyshch") print {-c[3:5]:"QQ"}
(3, 5, 7, 9, 2, 3, 4, 5) (8, 7, 'Bdyshch', 'Bdyshch') {(4, 3): 'QQ'}
Создать три класса:
Trigon, обозначающий треугольник:
- заводится по трём сторонам
имеет методы square() (площадь) и perimeter() (периметр)
Pea, обозначающий грушу круг
заводится (NB!) по трём сторонам вписанного треугольника
имеет методы square() и perimeter()
TrigonPea (унаследованный от Trigon и Pea), обозначающий треугольную грушу
- заводится по трём сторонам
- периметр и площадь равны периметру и площади треугольника
имеет метод volume(), равный произведению периметра треугольника на площадь описанного круга
Неравенство треугольника проверять не надо.
t=mod.Trigon(3,4,5) p=mod.Pea(3,4,5) z=mod.TrigonPea(3,4,5) print "{:.6f}".format(t.square()) print "{:.6f}".format(t.perimeter()) print "{:.6f}".format(p.square()) print "{:.6f}".format(z.volume()) print "{:.6f}".format(z.square())
6.000000 12.000000 19.634954 235.619449 6.000000
Очередная алгоритмическая задачка, поупражнять мозг:
(QuadChain) Прямоугольник из цепи
Цепь состоит из прямых отрезков различной целой ненулевой длины, соединённых попарно в замкнутую ломаную. Ввести строку целых чисел через запятую — длины отрезков цепи. Вывести YES, если цепь можно превратить в прямоугольник с вершинами в четырёх различных вершинах ломаной. Если нельзя, вывести NO.
1, 3, 2, 2, 4, 4
YES