5597
Комментарий:
|
6709
|
Удаления помечены так. | Добавления помечены так. |
Строка 42: | Строка 42: |
* MRO C3 ( | * MRO C3 |
Строка 130: | Строка 130: |
'''TODO''' | 1.#0 Повторить [http://greenteapress.com/thinkpython2/html/thinkpython2016.html|15-ю]] и [[http://greenteapress.com/thinkpython2/html/thinkpython2017.html|16-ю]] главы учебника, прочитать и прощёлкать [[http://greenteapress.com/thinkpython2/html/thinkpython2018.html|17-ю]] и [[http://greenteapress.com/thinkpython2/html/thinkpython2019.html|18-ю]] главы учебника * Прочитать статьи про линеаризацию * Зачем в описании линеаризации участвует объединение линеаризаций родительских классов ''и самих классов'' (в лекциях я это опустил)? * Иными словами, чему служит выделенная часть: `L[C(B1 ... BN)] = C + merge(L[B1] ... L[BN],` '''''`B1 ... BN`'''''`)` * Много ли мы теряем от того, что C3, в отличие от обхода дерева, может завершиться неудачей? 1. Написать класс '''TODO''' |
Наследование
Долги за прошлый раз:
hasattr() и getattr()
__iter__()
__del__()
Наследование
Объектное планирование и ООП
ООП:
Характеристика |
Python3 |
Инкапсуляция (не сокрытие) |
Иерархия пространств имён |
Наследование |
Наследование + C3 MRO |
Полиморфизм |
«Из коробки», т. к. duck typing |
Проксирование?
Хранить родительский объект в виде поля, а все методы нового класса делать обёрткой вокруг методов родительского объекта.
TODO пример
Простое наследование
- Видимость и перегрузка методов
- Преобразование типов и создание новых объектов текущего типа:
type(self)(…)
- Вызов метода родительского класса
super() — прокси-объект, аккумулирующий методы всех родительских классов (см. множественное наследование)
Защита полей от случайной перегрузки («__»)
Множественное наследование
- Проблема ромбовидного наследования:
Обход в глубину добирается до A.v раньше, чем до C.v
Обход в ширину добирается до A.v раньше, чем до B.v
Что нужно? Линеаризация:
- Монотонность C: [C, …, B, …, A] ⇒ D(...(C)...): [D, …, C, …, B, …, A]
Соблюдение порядка объявления: class C(D,E,F): … ⇒ `[C, D, E, F, …]
- ⇒ Некоторые ситуации невозможны
- MRO C3
- Общий принцип
- Линеаризация графа наследования классов — это объединение списка линеаризаций всех непосредственных родительских классов
- Объединение — это упорядочивание списка линеаризаций по следующему принципу:
- Рассматриваем список слева направо
Если очередной класс не является ничьим предком из списка, он добавляется в линеаризацию, а из списка удаляется
- переход к п. 1.
- Если очередной класс является чьим-то предком (входит в какую-то линеаризацию не в начало), переходим к следующему классу
- Если хороших кандидатов не нашлось, линеаризация невозможна
- Пример (слегка упрощённый):
- Простое наследование (L[X] — линеаризация класса X):
L[O] = O L[D] = D O L[E] = E O L[F] = F O
- Множественное наследование
L[B] = B + merge(DO, EO) D? Good L[B] = B + D + merge(O, EO) O? Not good (EO) E? Good L[B] = B + D + E + merge(O, O) O? Good L[B] = BDEO
соответственно,L[C] = CDFO
наконец,L[A]: A + merge(BDEO,CDFO) B? + A + B + merge(DEO,CDFO) D? × C? + A + B + C + merge(DEO,DFO) D? + A + B + C + D + merge(EO,FO) E? + A + B + C + D + E + merge(O,FO) F? + A + B + C + D + E + F + merge(O,O) O? + ABCDEFO
То есть:>>> A.mro() [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.E'>, <class '__main__.F'>, <class 'object'>]
Но если (B(E,D) вместо B(D,E)):
то>>> B.mro() [<class '__main__.B'>, <class '__main__.E'>, <class '__main__.D'>, <class 'object'>] >>> A.mro() [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <class 'object'>]
- Простое наследование (L[X] — линеаризация класса X):
super(): как всегда — объект-прокси всех методов родительских классов, в в случае множественного наследования аналогов не имеет (это как бы объект несуществующего класса)
Д/З
Повторить [http://greenteapress.com/thinkpython2/html/thinkpython2016.html|15-ю]] и 16-ю главы учебника, прочитать и прощёлкать 17-ю и 18-ю главы учебника
- Прочитать статьи про линеаризацию
Зачем в описании линеаризации участвует объединение линеаризаций родительских классов и самих классов (в лекциях я это опустил)?
- Иными словами, чему служит выделенная часть:
L[C(B1 ... BN)] = C + merge(L[B1] ... L[BN], B1 ... BN)
- Много ли мы теряем от того, что C3, в отличие от обхода дерева, может завершиться неудачей?
- Прочитать статьи про линеаризацию
Написать класс TODO