Объектная модель Python; декораторы
Долги за прошлый раз
Разбор решения задачи платная лестница
Параметрические генераторы
Параметрические: .send(par) вместо .next() ( ⇒ par = yield)
Управление: .close() и .throw(исключение)
Пример:
1 def pargen(n):
2 c = 1
3 for i in xrange(n):
4 c = yield i+c
5
6 def excgen(n):
7 for i in xrange(n):
8 try:
9 yield i*2+1
10 except NotImplementedError:
11 print "Haha, Got it!"
12
13 print "Sending a value within generator:"
14 a=pargen(20)
15
16 print "Initial:", a.next()
17 for s in [1,-20,0]:
18 print s,a.send(s)
19
20 print "Now closing, immediate StopIteration expected"
21 a.close()
22 for r in a: print "!!!Should be no more iterations!!!", r
23 print
24
25 print "Throwing NotImplementedError sometimes:"
26 s=excgen(6)
27 for r in s:
28 print r
29 if(r%3 == 0):
30 s.throw(NotImplementedError)
31
32 print "Done"
Обмен данными при запуске процессов
- Перенаправление В/В (в т. ч. в канал)
Проблема буферизации В/В (когда завершается операция write?)
- Проблема синхронизации В/В
POSIX diff, итеративная сущность Differ-объекта в difflib
Разбор ../Homework_TaskTester (FrBrGeorge/TaskTester.py, ../Homework_TaskTester.zip)
Классы и объекты в Python
- Проблема пересекающихся пространств имён и её решение — инкапсуляция. Поля как метод её реализации.
<объект>.<метод>(…) == <тип_объекта>.<метод>(<объект>, …)
суть функции type()
Поля __dict__ класса и экземпляра
Конструктор объекта — класс
- Динамическая природа полей объекта
- Правила видимости полей объекта и полей класса
<объект>.<метод>(…) == <класс>.<метод>(<объект>, …)
⇒ договорённость о self при задании метода
__init__()
- (Статические методы и методы класса — см. далее)
Перегрузка операций
Спецметоды и duck typing
- Обзор
- «Правые» варианты бинарных операций
- Упражнение: двумерные координаты (с операцией сложения)
- Преобразование результата операций
__getattr__()/__setattr_()/__delattr__()
BTW, hasattr()
Старые и новые классы в Python2
self.__class__ vs. type(self)
__getattribute__() (datamodel.html и далее по сылкам)
Наследование и полиморфизм
- Объектное планирование и его поддержка в ЯП
- Иерархия классов, механизм наследования как реализация
- Пример: список с поэлементным сложением вместо конкатенации
- В каком пространстве имён выполняется унаследованный код?
Преобразование выражений к текущему типу (type(self)(…) или self.__class__(…) вместо MyClass(…))
- Duck typing как платформа для полиморфизма
«__» — защита от случайной перегрузки родительских полей
issubclass(), isinstance()
- Старые классы: depth-first, left-to-right
Новые классы: (MRO C3)
ООП = «модульность, инкапсуляция, полиморфизм»
Разное:
Задание исключений
Исключение — любой класс (в raise можно передавать экземпляр, особенно если __init__ с параметрами)
- Иерархия исключений — наследование классов
Текст исключения — метод .__str__()
Декораторы
Шаблон программирования: «обёртка»:
- отладка, профилирование, сопутствующие действия, преобразование входа и/или выхода, …
Python: проверка типов параметров и возвращаемого значения, всякое см. модуль decorator
Python: динамическое создание функции-обёртки:
Что то же самое:
Примеры: @classmethod, @staticmethod, в новых классах — @property (с помощью .__getattribute__()).
1 class C(object):
2 def __init__(self, n):
3 self.__x=n
4
5 @property
6 def x(self):
7 return self.__x
8
9 # Проверить, что будет, если удалить эти три строки
10 @x.setter
11 def x(self,n):
12 self.__x=n
13
14 def simple(*args):
15 print "Simple:",args
16
17 @staticmethod
18 def stat(*args):
19 print "Static:",args
20
21 @classmethod
22 def cla(*args):
23 print "Classmethod",args
24
25 c=C(123)
26 print c.x
27 c.x=321
28 c.simple(1,2,3)
29 c.stat(1,2,3)
30 c.cla(1,2,3)
Параметрический декоратор — второй уровень косвенности, функция, возвращающая декоратор:
Декораторы бывают и у классов
Д/З
Прочитать
Про классы в учебнике (на русском)
Про спецметоды в справочнике
Статью на Хабре Сила и красота декораторов
Примеры декораторов в конце pep-0318
Задачи и упражнения
(SimpleVector) Вектора на плоскости
Реализовать класс Vector, позволяющий
- задавать двумерный вектор (из двух чисел)
- вычислять вектор — сумму двух векторов
- вычислять вектор — результат умножения вектора на число (или числа на вектор)
- скалярно умножать вектор на вектор
преобразовывать вектор в строку вида |x,y|
|1,2| |4,6| 11 |7,14|
Реализовать класс Vovel, у объекта которого можно получить значение любого поля, если имя этого поля состоит только из маленьких гласных латинских букв. Значение это — строка, совпадающая с именем поля, только состоящая из больших латинских букв. В противном случае поведение объекта должно быть естественным (вызывть исключение AttributeError, как минимум с тем же сообщением, что и «естественный» AttributeError в случае несуществующего поля). Реализовывать что-то, кроме получения значения поля, не надо.
AOAO ERROR Vovel instance has no attribute 'field'
(domari:SelfishTuple) Выворачиваемый кортеж
Определить класс MTuple, проксирующий тип tuple, с добавлением в него единственной операции — унарного минуса (операция возвращает MTuple с элементами в обратном порядке). Прочие операции также должны возвращать MTuple вместо tuple.
(3, 5, 7, 9, 2, 3, 4, 5) (8, 7, 'Bdyshch', 'Bdyshch') {(4, 3): 'QQ'}
(domari:ArgsChecker) Проверка параметров функции
Написать декоратор chkargs(тип1, тип2, …, типN), проверяющий, что у функции N параметров, и что они, соответственно, типа тип1, тип2, … , типN. В противном случае бросать исключение TypeError.
QqQqQqQqQq Parameter 1 of fun should be <type 'str'> (<type 'int'> given) fun takes exactly 2 arguments (3 given)