Декораторы и модуль functools

  Переглядів 39,725

Computer Science Center

Computer Science Center

8 років тому

compscicenter.ru/
Синтаксис декораторов. Декораторы с аргументами, без аргументов. Примеры использования декораторов. Модуль functools.
Лекция №3 в курсе "Python" (осень 2015).
Преподаватель курса: Сергей Лебедев
Страница лекции на сайте CS центра: goo.gl/i1ljox

КОМЕНТАРІ: 32
@vadimkovrizhkin7412
@vadimkovrizhkin7412 7 років тому
Лекции отличные. Не скучно. Просто супер. Читать книгу Бизли и параллельно закреплять лекциями очень круто. Было бы круто, видеть еще и куда указывает (код) лектор при объяснении :)
@victorklimov5254
@victorklimov5254 8 років тому
Лекции просто шикарны! Сергей, огромное спасибо!
@user-if1dj7fy2y
@user-if1dj7fy2y 10 днів тому
Чудесно звучит 🎉 а Когда же будет продолжение этой темы разговора 😮
@AdenConor
@AdenConor 8 років тому
50:18 все-таки пример со скобками ещё больше сбивает ident = square(addsome(ident)). потому что везде вызов функций происходит изнутри.
@aalexren
@aalexren Рік тому
Согласен, кажется , что сначала должен быть вызван addsome и только потом sqaure, а на деле получается обратный порядок, потому что эти декораторы возвращают функции, а не значения. 🤯
@dmitrievanton81
@dmitrievanton81 3 роки тому
Я прочитал несколько вопросов в этой ветке и понял, что не сразу понятно в этой лекции. Здесь нужно держать контекст предыдущей лекции и понятие LEGB о связывании переменных и областях видимости. Если убрать все "лишнее", чтобы не замыливало глаза (всякие декорации внутри декораций @...): def with_arguments(deco): def wrapper(*dargs, **dkwargs): def decorator(func): result = deco(func, *dargs, **dkwargs) return reslut return decorator return wrapper То лучше было бы сказать так: в момент, когда происходит выполнение строчки: @with_arguments: def trace(func, handle): ... происходит следующее: 1) wrap = with_arguments(trace); # на месте deco сейчас "указатель" на функцию wrapper(*dargs, **dkwargs) (для тестирования и отладки прямо так и можно заменить этот синтаксический сахар). 2) внутри функции wrapper(*dargs, **dkwargs) во всех местах использования переменной "deco" она "подменяется" на "trace". На самом деле deco=trace вроде бы как являестя enclosure переменной (LEGB из прошлой лекции). Во многих книжках эта подстановка называется замыканием: как только встретился подобный вызов функции содержащей определения других функций все внутренние функции "тащут" всесь контекст функции выше по иерархии. Получается что-то вроде: wrap:= def wrapper(*dargs, **dkwargs): def decorator(func): result = trace(func, *dargs, **dkwargs) return reslut return decorator 3) теперь нам нужно передать параметры в эту функцию wrap:=wrapper(*dargs, **dkwargs): - когда мы делаем вызов @trace(handle) identity(): ... у нас происходит замена: deco = wrap(handle) - заменяется на: deco:= #def wrapper(handle): - строчка для наглядности def decorator(func): result = trace(func, handle) return reslut # return decorator - строчка для наглядности - получается: deco:= def decorator(func): result = trace(func, handle) return reslut - потом происходит последняя подмена: identity = deco(identity); newidentity:= def decorator(identity): result = trace(identity, handle) return reslut Т.е на выходе у нас получился вызов декоратора с параметром handle. П.С. Не совсем понятно как это соотносится с " Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. " ? Читая код на питоне я должен держать в уме что там эта декорация декорирует. Я полагаю, что более чем для отладки и каких-то тестовых функций эти декорации лучше не использовать, т.к. отловить ошибку будет вообще не реально. Декорации никак не должны влиять на результат декорируемой функции и задекорированная функция должна в точности возвращать результат исходной.
@nprnaturepresenceonroofs2343
@nprnaturepresenceonroofs2343 3 роки тому
спасибо громадное,у меня тоже было недопонимание ,как интериоризировать эти декораторы.Ведь как Вы правильно заметили,они не входят в логику импорт зис.
@vlad071096
@vlad071096 8 років тому
У вас в вашем with_arguments названия wrapper и decorator перепутаны семантически.
@user-vw1kt5pg3z
@user-vw1kt5pg3z 6 років тому
26:52 нет ли ошибки? Если я все правильно понимаю, в принте нужно указать handle.
@hansolo5665
@hansolo5665 4 роки тому
ага, я тоже долго его искал на слайде
@user-bk3qp1yp6k
@user-bk3qp1yp6k 2 роки тому
Для меня во время(после) просмотра было не явным что вот такой синтаксис: @decorator(argument) - это два вызова 1) первый - это вызов функции decorator с параметром argument 2) второй - это вызов того что вернул первый вызов с параметром имя функции(которую мы декорируем) Простой(сложный) пример который это объясняет(доказывает): def decorator(x): print(x) return(x) @decorator(print) def anyfunc(): pass output: Итог: @decorator(argument) - это два вызова
@secondmodu7184
@secondmodu7184 7 років тому
24:50 можно ли сказать что в def wrapper(*dargs, **dkwargs) dargs включает в себя аргументы trace, то есть func и handle ?
@slebedev
@slebedev 7 років тому
Нет, dargs содержит только аргументы декоратора. В случае trace это handle. func передаётся во внутреннюю функцию wrapper.
@secondmodu7184
@secondmodu7184 7 років тому
понятно, спасибо
@secondmodu7184
@secondmodu7184 7 років тому
36:05 а как так получается что inner.calls не переопределяется на False? Почему оно остается True? initialize_settings()...............................# Initialization is done print(initialize_settings.called)............# True initialize_settings() print(initialize_settings.called)............# True
@VladislavMikhalchuk
@VladislavMikhalchuk 2 роки тому
у меня все работает
@moduchanyu4025
@moduchanyu4025 7 років тому
05:00 а почему так происходит, почему при foo = trace(foo) foo.__name__ или trace(foo).__name__ возвращает нам имя inner функции, а не имя функции trace ?
@slebedev
@slebedev 7 років тому
trace(foo) возвращает нам свою внутреннюю функцию, которая называется inner, поэтому и __name__ у неё "inner", а не "identity". Отвлечённый пример: >>> def foo(): pass >>> foo.__name__ "foo"
@secondmodu7184
@secondmodu7184 7 років тому
36:47 у меня тоже вопрос насчет return почему в этом случае возвращается None?: def once(func): ........@functools.wraps(func) ........def inner(*args, **kwargs): ................if not inner.called: ........................inner.called = True ........................func(*args, **kwargs) ........inner.called = False ........return inner @once def foo(): return("Initialization is done") print(foo()) # None
@VladislavMikhalchuk
@VladislavMikhalchuk 2 роки тому
в foo передай аргумент
@user-zi8ve6fv1t
@user-zi8ve6fv1t 6 років тому
Ребята, выложите домашние задания!
@CompscicenterRu
@CompscicenterRu 6 років тому
Задачи доступны только студентам CS центра (набор раз в год в Питере и Новосибе).
@nicholasspezza9449
@nicholasspezza9449 Рік тому
Использовать "assert" для проверки условия ... хм ... а дяденька точно хороший программист? Или в те года это было хорошей практикой.
@user-zj3ih2ux5e
@user-zj3ih2ux5e Рік тому
До сих пор пишем assert. Когда нет определенного ексепшена, ассерт проще всего.
@dmitriynovikov3421
@dmitriynovikov3421 3 роки тому
Скажу честно мне непонятно почему identity = addsome(identity) identity = square(identity) равно вот этому identity = square(addsome(identity)) Какая то контринтуитивная история, как то ожидается что addsome а потом square но нет....
@romansafronov6628
@romansafronov6628 Рік тому
Хм
@user-zk6tw7rj1t
@user-zk6tw7rj1t 3 роки тому
видно хороший программист, но объясняет сухо для бывалых
@79Striker79
@79Striker79 3 роки тому
Согласен однозначно, зелёному новичку, который впервые в жизни решил попробовать изучить язык программирования, да при том, что сам по натуре гуманитарий - тут ловить нечего. Курс лекций рассчитан на технарей, причём очень способных.
@vlad071096
@vlad071096 8 років тому
Сказали бы "фабрика декораторов" вместо "параметризованный декоратор", все бы сразу все поняли.
@mk05h31
@mk05h31 7 років тому
на собеседованиях обычно просят написать "декоратор с параметрами"
@boobubuo
@boobubuo 3 роки тому
супер не понятно .. галопом по европам .. ДЛЯ КОГО эта лекция ????
@79Striker79
@79Striker79 3 роки тому
Для бывалых технарей.
Всё, что вы хотели знать о функциях в Python
1:24:51
Computer Science Center
Переглядів 72 тис.
Functools is one of the MOST USEFUL Python modules
13:37
Carberra
Переглядів 29 тис.
Їжа Закарпаття. Великий Гід.
1:00:29
Мiша Кацурiн
Переглядів 624 тис.
Как устроены декораторы в python?
12:18
Хитрый питон
Переглядів 14 тис.
You Can Do Really Cool Things With Functions In Python
19:47
ArjanCodes
Переглядів 213 тис.
Строки, байты, файлы и ввод/вывод
1:12:20
Computer Science Center
Переглядів 21 тис.
Python's Magical Itertools Module
14:33
Tech With Tim
Переглядів 78 тис.
Вселенная и Специальная теория относительности.
3:51:36
ЗЛОЙ АНАЛИТИК ВСЕЛЕННОЙ.
Переглядів 6 млн
Декораторы Python | Разбираем Декораторы  С Примерами Кода
10:28
PyLounge - программирование на Python и всё о IT
Переглядів 16 тис.
#1 | Python NumPy | Что такое array, arange и dot
8:12
Псевдо Программист
Переглядів 14 тис.
Partial Functions in Python - Functools Tutorial
14:12
NeuralNine
Переглядів 15 тис.