Тёмный

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

Computer Science Center
Подписаться 160 тыс.
Просмотров 40 тыс.
50% 1

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

Опубликовано:

 

30 сен 2015

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 32   
@vadimkovrizhkin7412
@vadimkovrizhkin7412 7 лет назад
Лекции отличные. Не скучно. Просто супер. Читать книгу Бизли и параллельно закреплять лекциями очень круто. Было бы круто, видеть еще и куда указывает (код) лектор при объяснении :)
@victorklimov5254
@victorklimov5254 8 лет назад
Лекции просто шикарны! Сергей, огромное спасибо!
@user-if1dj7fy2y
@user-if1dj7fy2y 22 дня назад
Чудесно звучит 🎉 а Когда же будет продолжение этой темы разговора 😮
@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 года назад
ага, я тоже долго его искал на слайде
@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 года назад
у меня все работает
@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 лет назад
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 передай аргумент
@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"
@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 года назад
Для бывалых технарей.
Далее
Многопоточность и GIL
1:21:47
Просмотров 34 тыс.
Partial Functions in Python - Functools Tutorial
14:12
You Can Do Really Cool Things With Functions In Python
19:47