Различия между версиями 11 и 12
Версия 11 от 2019-11-26 16:52:22
Размер: 5504
Редактор: FrBrGeorge
Комментарий:
Версия 12 от 2019-11-26 16:53:17
Размер: 5503
Редактор: FrBrGeorge
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 48: Строка 48:
Реализованы с помощью [[py3how:/descriptor.html|дескрипторов]] (см. след. лекцию) Реализованы с помощью [[py3how:descriptor.html|дескрипторов]] (см. след. лекцию)

Объектная модель 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)

Последовательности и прочие хранилища

  • __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

Реализованы с помощью дескрипторов (см. след. лекцию)

  • @classmethod

  • @staticmethod

  • @property

    • Это декоратор вокруг протокола дескрипторов
    • Модель
      •    1 class C:
           2     def __init__(self):
           3         self._x = None
           4 
           5     def getx(self):
           6         return self._x
           7 
           8     def setx(self, value):
           9         self._x = value
          10 
          11     def delx(self):
          12         del self._x
          13 
          14     x = property(getx, setx, delx, "I'm the 'x' property.")
        
    • Декораторы: @property (это getter) / @setter / @deleter:

         1     @property
         2     def x(self):
         3         """I'm the 'x' property."""
         4         return self._x
         5 
         6     @x.setter
         7     def x(self, value):
         8         self._x = value
         9 
        10     @x.deleter
        11     def x(self):
        12         del self._x
      
    • см. пример

Д/З

  1. Прочитать про классы в tutorial; про «волшебные методы» например, тут

  2. EJudge: DahDit 'Морзянка'

    Написать класс morse("строка"), экземпляр которого переводит арифметические выражения в морзянку! Параметр «строка» бывает разных видов, более подробно описан в подсказках, желающие могут догадаться о его компонентах по примеру (пример почти полный). «+» — точка, «-» — тире, «~» — промежуток между буквами (бывает только между буквами и только один, проверять не надо).

    Input:

       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 ///")) 
    
    Output:

    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///
  3. EJudge: CyberSausage 'Киберколбаса'

    Написать класс sausage, имитирующий киберколбасу. Киберколбаса может быть проинициализирована нулём значений (создаётся колбаса по умолчанию), одним (фарш) и двумя (фарш и объём). Длина целого батона киберколбасы 12 символов фарша и 2 оболочки. Колбаса единичного объёма — это один полный батон, более, чем единичного — это несколько батонов (последний, возможно, неполон). Неполный батон заканчивается срезом. Киберколбаса поддерживает операции умножения и деления на целое число, а также сложения и вычитания с другой киберколбасой (фарш результата совпадает с фаршем первого операнда). Если объём киберколбасы нулевой, батон считается пустым.

    Input:

       1 a, b, c = sausage(), sausage("HAM", "5/6"), sausage("SPAM.", 1.25)
       2 print(a, b, c, sep="\n")
       3 print(a+b+c)
       4 print(b*2, 4*c/5, sep="\n")
       5 d, e = b+a/6-5*c/4, a-c
       6 print(d, not d)
       7 print(e, not e)
    
    Output:

    /------------\
    |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
  4. EJudge: SelfCount 'Сколько экземпляров'

    Написать класс WeAre, объекты которого содержат поле count, содержащее количество существующих экземпляров этого класса. Игнорировать попытки изменить значение этого поля вручную или удалить его.

    Input:

       1 a = WeAre()
       2 print(a.count)
       3 b, c = WeAre(), WeAre(),
       4 a.count = 100500
       5 print(a.count, b.count, c.count)
       6 del b.count
       7 del b
       8 print(a.count)
    
    Output:

    1
    3 3 3
    2

LecturesCMC/PythonIntro2019/10_ObjectModel (последним исправлял пользователь FrBrGeorge 2019-11-26 16:53:17)