Различия между версиями 14 и 15
Версия 14 от 2017-11-13 12:32:48
Размер: 5599
Редактор: FrBrGeorge
Комментарий:
Версия 15 от 2017-11-13 12:35:21
Размер: 5583
Редактор: FrBrGeorge
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 133: Строка 133:
----
'''TODO'''

Введение в классы

Pазбор Д/З

Ещё про словари

Классы

(базовая статья «Классы в Python3 — это очень просто»)

Пространства имён:

  • Встроенные объекты
  • locals()/globals()__builtins__()

  • Модули
    • BTW: запуск модуля как программы, __name__

  • Всё это неуниверсально ⇒ классы

Замена dir() для просмотра списка методов, чьё имя не начинается на «"_"»:

   1 def Dir(obj):
   2      return [d for d in dir(obj) if not d.startswith("_")]
  • Классы как пустой горшокпространства имён: инкапсуляция

    •    1   class C:
         2       pass
      
    • туда что хочешь можно положить!
  • Классы как конструкторы объектов:
    • Если класс вызвать как функцию, он породит экземпляр класса (объект)

         1   class C:
         2       pass
         3 
         4   b = C()
      
    • Объект:
      • Точка доступа к полям класса
      • Может содержать свои поля: поле объекта «загораживает» поле класса с те же именем
    • Содержимое конструктора класса — заполнение его пространства имён. Доступ к полям класса/объекта, разумеется, возможен только с помощью объекта, в чьём пространстве имён находится поле:

      •    1     class C:
           2         Var = 100500
           3 
           4     b = C()
           5     print(b.Var, C.Var)
        
    • Методы. Если в класс положить функцию, а посмотреть на неё через его экземпляр (объект), функция превратится в метод
      •    1 >>> def fun(a):
           2 ...     return a*2+1
           3 ...
           4 >>> fun
           5 <function fun at 0x7efbfe418ae8>
           6 >>> C.foon=fun
           7 >>> C.foon
           8 <function fun at 0x7efbfe418ae8>
           9 >>> b=C()
          10 >>> b.foon
          11 <bound method fun of <__main__.C object at 0x7efbfe430c88>>
        
      • Метод отличается от функции только тем, что ему дополнительно в качестве нулевого параметра передаётся объект, через который мы смотрим на эту функцию:

        •    1 >>> def fun(*argp):
             2 ...     print(*argp)
             3 ...
             4 >>> fun
             5 <function fun at 0x7efbfe418f28>
             6 >>> fun(1,2,"QQ")
             7 1 2 QQ
             8 >>> C.foon=fun
             9 >>> C.foon
            10 <function fun at 0x7efbfe418f28>
            11 >>> C.foon(1,2,"QQ")
            12 1 2 QQ
            13 >>> b
            14 <__main__.C object at 0x7efbfe430c88>
            15 >>> b.foon(1,2,"QQ")
            16 <__main__.C object at 0x7efbfe430c88> 1 2 QQ
          
      • таким образом можно обращаться к полям этого объекта (или к полям класса, если полей объекта нет)
        •    1 >>> class C:
             2 ...     Var = 100500
             3 ...
             4 ...     def fun(self, add):
             5 ...         self.Var += add
             6 ...
             7 >>> b = C()
             8 >>> b.Var
             9 100500
            10 >>> b.fun(42)
            11 >>> b.Var
            12 100542
          

          имя этого нулевого параметра может быть каким угодно, «self» — просто конвенция

  • Спецметод .__init__() вызывается всегда после создания объекта, но перед тем, как конструктор вернёт его пользователю. В нём можно заполнять поля именно объекта:

    •    1 >>> class C:
         2 ...     def __init__(self):
         3 ...         self.Var = 0
         4 ...         self.Other = 42
         5 ...
         6 >>> dir(C)
         7 ['__class__', …]
         8 >>> b = C()
         9 >>> dir(b)
        10 ['Other', 'Var', '__class__', …]
        11 >>> b.Other
        12 42
      
    • Конструктор объекта можно вызвать с параметрами, они передадутся __init__()

         1 >>> class C:
         2 ...     def __init__(self, start, add):
         3 ...         self.value = start
         4 ...         self.add = add
         5 ...     def incr(self):
         6 ...         self.value += self.add
         7 ...
         8 >>> d = C(100,500)
         9 >>> dir(d)
        10 ['__class__', …, 'add', 'incr', 'value']
        11 >>> d.value
        12 100
        13 >>> d.incr()
        14 >>> d.value
        15 600
      

Д/З

  • Прощёлкать FrBrGeorge/ClassesInPython3

  • Прочитать
  • Как оформлять Д/З типа «написать класс»

  • EJudge: DummyClass 'Просто класс'

    Написать класс Delay, экземпляры которого содержат объект slot (задаётся конструктором) и метод delay(new), который присваивает slot новое значение new, а возвращает предыдущее значение slot.

    Input:

    de = Delay(100500)
    print(de.delay(42))
    print(de.delay(0))
    print(de.slot)
    print(*sorted(s for s in dir(de) if not s.startswith("_")))
    Output:

    100500
    42
    0
    delay slot
  • EJudge: CountInt 'Целые поля'

    Ввести (с помощью eval(input())) некоторый объект Python3 и посчитать, склько у него целочисленных полей (включая спецполя, имя которых начинается на "_").`

    Input:

    100500
    Output:

    4
  • EJudge: SharedBrain 'Единый мозг'

    Написать класс Overall, в котором будет единственный метод .click(), возвращающий количество вызовов этого метода у всех экземпляров класса Overall.

    Input:

    a, b = Overall(), Overall()
    print(a.click())
    print(b.click())
    print(b.click())
    print(a.click())
    Output:

    1
    2
    3
    4
  • EJudge: NormalDouble 'Простой и двойной'

    Написать два класса — Normal и Double, в каждом из которых будет два метода — .swap(other) и .what().__init__(start), задающий начальное значение некоторому полю. Метод .what() класса Normal должен возвращать значение этого поля, а .swap(other) — менять местами значния полей текущего объекта и объекта other. Аналогичные методы класса Double должны все значения умножать на 2: само поле — при инициализации и обмене (у обоих объектов), возвращаемое значение — в методе .what()

    Input:

       1 a = Normal(3)
       2 b = Double(1)
       3 print(a.what(), b.what())
       4 a.swap(b)
       5 print(a.what(), b.what())
       6 b.swap(a)
       7 print(a.what(), b.what())
    
    Output:

    3 4
    2 6
    6 8

LecturesCMC/PythonIntro2017/08_Classes (последним исправлял пользователь FrBrGeorge 2017-11-13 12:35:21)