Различия между версиями 10 и 11
Версия 10 от 2018-11-25 11:47:43
Размер: 5597
Редактор: FrBrGeorge
Комментарий:
Версия 11 от 2018-11-26 12:12:13
Размер: 6709
Редактор: FrBrGeorge
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 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() — прокси-объект, аккумулирующий методы всех родительских классов (см. множественное наследование)

  • Защита полей от случайной перегрузки («__»)

Множественное наследование

  • Проблема ромбовидного наследования:
    • 1.1.png

      • Обход в глубину добирается до A.v раньше, чем до C.v

    • 2.3.png

      • Обход в ширину добирается до 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
    • https://makina-corpus.com/blog/metier/2014/python-tutorial-understanding-python-mro-class-search-path

    • https://habr.com/post/62203/

    • https://ru.wikipedia.org/wiki/C3-линеаризация

    • Описание с примерами

    • Общий принцип
      • Линеаризация графа наследования классов — это объединение списка линеаризаций всех непосредственных родительских классов
      • Объединение — это упорядочивание списка линеаризаций по следующему принципу:
        1. Рассматриваем список слева направо
        2. Если очередной класс не является ничьим предком из списка, он добавляется в линеаризацию, а из списка удаляется

          • переход к п. 1.
        3. Если очередной класс является чьим-то предком (входит в какую-то линеаризацию не в начало), переходим к следующему классу
        4. Если хороших кандидатов не нашлось, линеаризация невозможна
    • Пример (слегка упрощённый):
         1 O = object
         2 class F(O): pass
         3 class E(O): pass
         4 class D(O): pass
         5 class C(D,F): pass
         6 class B(D,E): pass
         7 class A(B,C): pass
      
      • Простое наследование (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)):

           1 O = object
           2 class F(O): pass
           3 class E(O): pass
           4 class D(O): pass
           5 class C(D,F): pass
           6 class B(E,D): pass
           7 class A(B,C): pass
        
        то
        >>> 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'>]
  • super(): как всегда — объект-прокси всех методов родительских классов, в в случае множественного наследования аналогов не имеет (это как бы объект несуществующего класса)

Д/З

  1. Повторить [http://greenteapress.com/thinkpython2/html/thinkpython2016.html|15-ю]] и 16-ю главы учебника, прочитать и прощёлкать 17-ю и 18-ю главы учебника

    • Прочитать статьи про линеаризацию
      • Зачем в описании линеаризации участвует объединение линеаризаций родительских классов и самих классов (в лекциях я это опустил)?

      • Иными словами, чему служит выделенная часть:
        • L[C(B1 ... BN)] = C + merge(L[B1] ... L[BN], B1 ... BN)

      • Много ли мы теряем от того, что C3, в отличие от обхода дерева, может завершиться неудачей?
  2. Написать класс TODO

LecturesCMC/PythonIntro2018/10_Inheritance (последним исправлял пользователь FrBrGeorge 2018-11-28 01:21:53)