Повторное использовние, декораторы, оператор with
Сборочное программирование и повторное использование
- Мечта: сборочное программирование. Повторное использование (и, внезапно, наше ejudge-тестирование): просто алгоритмы (вход-выход), unix way/Microsoft way. ООП. Повторно используемые библиотеки классов. Внезапно, Docker (повторное использование контейнеризованных приложений).
- Алгоритмы + структуры данных = программы. More than this!
- Аспектно-ориентированное программирование.
- Веб-разработка: статические сайты из ФС, немного включенной динамики (PHP), много динамики (...)
- Django: роутинг запросов по шаблонам (вместо ФС), парсинг URI на параметры, view как функция.
Декораторы
- Определение, синтаксис, смысл
- Пример с @staticmethod
- Пример из Django (декоратор login_required, общий декоратор under_construction).
Оператор with. ContextManager
- Проблема и варианты решения вручную
ContextManager и with
- библиотека contextlib
- декораторы contextmanager, closing
Д/З
(необязательное)
FunctionCachier. Написать декоратор function_cachier, который возвращает функцию, значения которой не вычисляются заново при повторных обращениях.
def f1(n): print 'f1 called' return n*n @mod.function_cachier def f2(n): print 'f2 called' return n*n*n print len([ f1(n) for n in range(3)]) print len([ f1(n) for n in range(3)]) print len([ f2(n) for n in range(4)]) print len([ f2(n) for n in range(4)])
f1 called f1 called f1 called 3 f1 called f1 called f1 called 3 f2 called f2 called f2 called f2 called 4 4
- Усложнение: научить его работать с рекурсивными функциями.
WithFunctionCachier. Из декоратора FunctionCachier сделать полноценный ContextManager:
def f1(n): print 'f1 called' return n*n def f2(n): print 'f2 called' return n*n*n print len([ f1(n) for n in range(3)]) with mod.with_function_cachier(f2) as f: print len([ f(n) for n in range(5)])
f1 called f1 called f1 called 3 5
- Усложнение: Сделать его повторно используемым между вызовами with, чтобы сохранялся однажды накопленный кэш функций.
Усложнение: Сделать его повторно используемым между вызовами программы