#45. Введение в декораторы функций | Python для начинающих

  Рет қаралды 74,144

selfedu

selfedu

2 жыл бұрын

Обучающий курс: stepik.org/course/100707
Что такое декораторы, как они определяются и применяются к функциям. Примеры их использования.
Telegram-канал: t.me/python_selfedu
#37. Алгоритм Евклида для нахождения НОД: • #37. Алгоритм Евклида ...
#43. Области видимости переменных: • #43. Области видимости...
#44. Замыкания в Python: • #44. Замыкания в Pytho...

Пікірлер: 104
@nikitaaspaev1638
@nikitaaspaev1638 8 ай бұрын
Посмотрел сначала видео Гоши Дударя. Ничерта не понял. Потом посмотрел ваше видео - разница в преподавании колоссальна! Вы просто безупречно, на простых примерах, объясняете тему, спасибо вам!
@onemasterlomaster1829
@onemasterlomaster1829 2 жыл бұрын
selfedu *Благодаря замыканию, у меня аж мозг замкнуло! Как это все запутано, 7 раз пересмотрел! Спасибо Сергей без вас не разобрался бы!*
@user-wr5rc5pp8r
@user-wr5rc5pp8r 2 жыл бұрын
учил о декораторах на другом канале. Думал даже, что понял суть. Но сейчас проходя заново курс "ООП простыми словами" начинаю усваивать вопросы гораздо глубже.
@user-lq4pv8lj5q
@user-lq4pv8lj5q Жыл бұрын
с четвёртого раза нашёл ролик, который понятно простым языком объясняет, что такое декораторы, спасибо!
@qryak
@qryak 10 ай бұрын
пожалуй это самая сложная тема после рекурсии, с вашими уроками хоть как-то начал ее понимать)
@user-tb2jp7kg2c
@user-tb2jp7kg2c 2 жыл бұрын
Сергей, спасибо! Курс крутой, возможно когда-нибудь дойдем до асинхронности в Python, был бы рад послушать и изучить в вашей интерпретации информацию про asyncio и т.д.
@AZ993k
@AZ993k Жыл бұрын
Да так не то до асинхронности можно дойти, но и до паттернов проектирования на питоне :) Ме, например, очень нравился всегда C#, учить я его пытался в основном самостоятельно (были курсы, но неудачные). Но по сравнению с C# питон заходит намного быстрее. Думаю, дело в преподавателе
@user-bp7nu3eu8d
@user-bp7nu3eu8d Жыл бұрын
Все очень понятно изложено, спасибо! Теперь не понимаю, как я могла этого не понимать))
@SovsemNeProstoy
@SovsemNeProstoy Жыл бұрын
Как-же вы всё прекрасно разжевали нам, за несколько жалких минут понял то, что не понимал в течении месяца. *чувства искренней благодарности*
@nedestro
@nedestro 2 жыл бұрын
Сперва смотрел прошлый вариант видео (от 16 мар. 2020) и там к середине мозги начали заворачиваться, я несколько раз на паузу ставил, отматывал, потом просто досмотрел с чувством "пока рановато, позже обязательно раскурю". А здесь всё с ходу понятно! Декоратор был написан буквально "с полпинка", сижу довольный как слон )) Новая подача зашла шикарно, спасибо огромное!
@tinaanit2965
@tinaanit2965 2 ай бұрын
пришла по рекомендации из какого-то комментария ) и не пожалела , спасибо за ваше объяснений ! Развития вашему каналу🍀
@DobroDelo
@DobroDelo Жыл бұрын
Понятно, просто, доходчиво... вообщек как и все остальные уроку Сергея. Огромное спасибо за вашу работу!
@likeclockwork9600
@likeclockwork9600 2 жыл бұрын
Я тут цикл для себя написал, рекомендую ознакомиться. while ' Сергей выкладывает видео ': like += 1 comment += 1 print('Спасибо Сергей') else: print('Ждем новое видео')
@krab9241
@krab9241 2 жыл бұрын
пока иначе. а так можно было!?
@likeclockwork9600
@likeclockwork9600 2 жыл бұрын
@@krab9241 да , такое условие есть только у Пайтона. (после цикла можно поставить else) Но сам Гвидо говорил, если бы он заново начал делать Python, то не стал бы делать такое условие.
@KonstantinYurievich
@KonstantinYurievich 2 жыл бұрын
@@likeclockwork9600 'else' в 'while' используется в комбинации с 'break', иначе в 'else' нет смысла...
@novichok3417
@novichok3417 4 ай бұрын
Поздравляю вас с говнокодом! Создал бесконечный цикл. И зачем то увеличивал переменные like и comment
@user-ck2tv6pf6f
@user-ck2tv6pf6f 3 ай бұрын
@@novichok3417 +
@ruziliakalyon4168
@ruziliakalyon4168 2 жыл бұрын
Благодарю вас за обучение! Вы очень внимательный и ответственный учитель. Здоровья Вам и Вашим близким
@user_712_li
@user_712_li Жыл бұрын
Спасибо огромное, автор. Единственный, кто подробно всё объяснил.
@user-iq6uq4lx3l
@user-iq6uq4lx3l Жыл бұрын
@PythonRussian - объясняет просто "жесть", вообще МОЛОДЕЦ парнишка!Посмотри не прогадаешь - объясняет может даже лучьше
@86Blind
@86Blind 2 жыл бұрын
Огромное спасибо за урок!
@user-lf1ez2ln7h
@user-lf1ez2ln7h Жыл бұрын
Лучшие объяснения из тех что я видел, хотя я давно пишу на питоне, но именно изучить его захотелось сейчас
@konstantinsakharov227
@konstantinsakharov227 2 жыл бұрын
Спасибо, у Вас дар! Видел много курсов, так ясно, наглядно и без лишнего усложнения не объясняет никто на русском. Всего Вам наилучшего, 100500+ в карму =) Это касается всех курсов которые здесь размещены.
@andredru4278
@andredru4278 4 ай бұрын
Спасибо. Великолепно. Я понял.
@user-sm6ej3fl4m
@user-sm6ej3fl4m 9 ай бұрын
Спасибо, это единственное видео где я все понял. Смотрел других, пересматривал по 3 раза но не понял. Большое спасибо автору!
@MrSasuke1337
@MrSasuke1337 5 ай бұрын
Как я пожалел что не начинал смотреть на начальном этапе ваши курсы по базе и пока я смотрел ваш курс ооп, я не особо понимал как работают декораторы, но дойдя до сюда, я пиздец как понял
@user-yw6nt4zz4c
@user-yw6nt4zz4c Жыл бұрын
Спасибо! Очень подробно и простым языком, а главное понятно!
@kiber7575
@kiber7575 2 ай бұрын
мега круть про декораторы
@Grigorev84
@Grigorev84 2 жыл бұрын
Очень крутая подача, лучше ещё не видел!
@user-sb8zp4qn2y
@user-sb8zp4qn2y 9 ай бұрын
Спасибо большое вам, очень ценные уроки😊
@mksmvnv
@mksmvnv 8 ай бұрын
просто идеальное объяснение, спасибо вам большое)
@user-uk3qb9ex1b
@user-uk3qb9ex1b 3 ай бұрын
спасибо большое было очень полезно 🥰🥰🥰
@user-vo4pj6cm9h
@user-vo4pj6cm9h 9 ай бұрын
Отличное описание, автору спасибо!
@user-hw9eg2om3g
@user-hw9eg2om3g 7 ай бұрын
Хоть и понял со 2 раза, но материал понятен Огромное спасибо автору!
@vladimirkulakov6126
@vladimirkulakov6126 2 жыл бұрын
Ура! Декораторы! А ведь именно на этой теме я засыпался на первом собеседовании) маст хев! Спасибо за короткое и понятное видео, Сергей!
@user-tg3xw1cb2l
@user-tg3xw1cb2l 2 жыл бұрын
Сэр, Вы серьёзно? Не зная декораторов уже можно идти на собеседование?? Я думал это самое начало обучения...
@vladimirkulakov6126
@vladimirkulakov6126 2 жыл бұрын
@@user-tg3xw1cb2l собеседование это в том числе опыт, не попробуешь не узнаешь.
@Ybuotue
@Ybuotue 2 жыл бұрын
Едрён батон! Не один год работал с декораторами (которые художники), и только под конец видео поняв, что такое декораторы в питоне, на меня снизашло озарение, почему они названы так. Думаю если бы раньше связал два этих одинаковых слова, быстрее бы понял суть декорирования в питоне (считай ретушевание/корректировка/украшение фукнции). Вообще сильно помогла ссылка на Замыкания. Без замыканий реально было трудно понять суть и смысл. Спасибо.
@a.osethkin55
@a.osethkin55 Жыл бұрын
Спасибо!
@jetbrain9115
@jetbrain9115 2 жыл бұрын
Спасибо! Суппер!
@jamjam3337
@jamjam3337 Жыл бұрын
спасибо!👏👍
@user-ye1vt4mj1p
@user-ye1vt4mj1p Жыл бұрын
Доброго времени суток, Сергей, заметил, что при задании функции get_fast_nod следующего вида: def get_fast_nod(a, b): while b: a, b = b, a % b return a она работает аналогично тому определению, которые Вы предоставили в видео. (т.к. по факту, если a < b, то в строчке a, b = b, a % b они просто поменяются местами)
@user-rc7kz2qp9m
@user-rc7kz2qp9m Жыл бұрын
Супер, не знаю кто еще лучше может настолько понятно объяснить. Спасибо тебе большое)
@user-iq6uq4lx3l
@user-iq6uq4lx3l Жыл бұрын
@PythonRussian - объясняет просто "жесть", вообще МОЛОДЕЦ парнишка!
@user-vt3cq8eu8s
@user-vt3cq8eu8s 2 ай бұрын
Коммент в поддержку канала!)
@illiukhin
@illiukhin 2 жыл бұрын
спасибо
@drueserick4158
@drueserick4158 Жыл бұрын
Я понял это намек, я все ловлю на лету... Но чета я совсем... ... Бллагодаря Вам, все лучше :)
@mrrototo761
@mrrototo761 Жыл бұрын
Спасибо
@andruhaz
@andruhaz 2 жыл бұрын
Видимо всех замыкает на замыканиях)), но объяснение лучше чем у Била Любановича. Например меня заклинило на "КАААК можно передавать функции второе значение, когда ей уже раньше передали значение)) ПОЧЕМУ она его принимает". Видимо нужно еще раз перечитать вложенные функции)). Да и в принципе selfedu классно сделал, что показал, почему замыкание называется замыканием. Сразу практически все стало понятно. Еще стало понятно, что хочу поучить Фласк у selfedu
@bobby_ridge
@bobby_ridge 3 ай бұрын
Доброго времени суток. Спасибо за видео. Вопрос: могу ли я "продекорировать" функцию функцией-декоратором, в которой не замыкания?
@user-yo2oi7qz3l
@user-yo2oi7qz3l Жыл бұрын
Спасибо,Сергей! Видео понятное,но всё же пример с алгоритмом Евклида может запутать!
@mingboevnurullo
@mingboevnurullo 8 ай бұрын
Legend
@ibrahimoglu
@ibrahimoglu 2 жыл бұрын
👍
@impellergimpeller5133
@impellergimpeller5133 2 жыл бұрын
👍👍👍👍👍
@user-bw4xg8tb9r
@user-bw4xg8tb9r 2 жыл бұрын
Урок супер! Всё предельно понятно и примеры хорошие. Спасибо! P.S. Интересно почему при первом вызове декарируемой функции get_nod время вывелось 0,0329.. сек, а не 0,0269 сек, как в последствии и перед этим))
@selfedu_rus
@selfedu_rus 2 жыл бұрын
ОС Windows (скорее всего она у вас) - это не система реального времени и программы могут выполняться с разной скоростью
@Munchen888
@Munchen888 8 ай бұрын
def gcd(a, b): if a == 0 or b == 0: return a + b elif a > b: return gcd(a % b, b) elif b > a: return gcd(a, b % a) print(gcd(30, 18)) Нахождение НОД рекурсивно) Чтобы не забывать!
@user-rc9cz5ex6l
@user-rc9cz5ex6l Жыл бұрын
Сергей, я правильно понял, что на практике назначение декорирующей функции это расширение возможностей функции, которую мы декорируем т.е. some_func, не трогая саму функцию? И как тогда с помощью декорирующей функции поменять, к примеру, переменную которая находится в функции some_func?
@selfedu_rus
@selfedu_rus Жыл бұрын
Да, все верно. Набор параметров декорируемой функции, как правило, остается неизменным, но если хотите что то поменять, то прописывайте у def wrapper() это у будет набор параметров после декорирования.
@user-cp6ne8nr4u
@user-cp6ne8nr4u Жыл бұрын
Спасибо большое, все вполне понятно. Я только не поняла, зачем в принципе нужны декораторы. Ну нельзя ли что-то делать, потом вызывать функцию, потом снова что-то делать?
@selfedu_rus
@selfedu_rus Жыл бұрын
во фреймворках они везде и всюду )) очень удобная штука, с практикой усвоите этот момент
@alexzir
@alexzir Жыл бұрын
Подскажите пожалуйста, на Stepik у вас листинги кода прилагаются? И что там дополнительно есть?
@selfedu_rus
@selfedu_rus Жыл бұрын
дополнительно только практика
@Pawokify
@Pawokify Жыл бұрын
Я не понял почему нужно в wrapper тоже прописывать параметр title.. (Если не использовать args)
@guiterenzog2723
@guiterenzog2723 Жыл бұрын
Что по поводу __name__ и __doc__ при использовании нескольких декораторов?
@selfedu_rus
@selfedu_rus Жыл бұрын
да все то же самое, так где декорирование функции происходит, сохраняем __name__ и __doc__
@pokryshkin1973
@pokryshkin1973 Жыл бұрын
Если в классе есть setter для __old, то не разумно ли в методе __init__ прописать self.old = old вместо self.__old = old
@selfedu_rus
@selfedu_rus Жыл бұрын
да, разумно!
@pokryshkin1973
@pokryshkin1973 Жыл бұрын
@@selfedu_rus перепутал тему. хотел спросить в kzbin.info/www/bejne/g6nZmoCtl6yfaas&feature=share&EKLEiJECCKjOmKnC5IiRIQ
@user-jh3xl2ij3r
@user-jh3xl2ij3r 2 жыл бұрын
Видео за 13 минут, разбираюсь что происходит три часа((
@user-du8yk6eh5u
@user-du8yk6eh5u 2 жыл бұрын
Как всё работает понятно. Но зачем нужен wrapper? Если этот же код прописать во внешней функции test_time всё будет работать точно также. Каким образом используется замыкание?
@selfedu_rus
@selfedu_rus 2 жыл бұрын
вы тогда не сможете передавать аргументы функции (без wrapper), точнее передать только один раз
@nilmulyashov7274
@nilmulyashov7274 2 жыл бұрын
Ютуб не пропускает слишком большой коммент, так что буду частями) К примеру, у нас есть вот такие функции: def list_by_cycle(): lst = [] for i in range(100): if i % 2 == 0: lst.append(i) return lst def list_comprehension(): lst = [i for i in range(100) if i % 2 == 0] return lst И мы хотим посчитать их время работы, чтоб сравнить, какая быстрее. Это можно сделать так: import time def list_by_cycle(): start = time.perf_counter() # Замеряем время до отработки функции lst = [] for i in range(100): if i % 2 == 0: lst.append(i) return lst def list_comprehension(): start = time.perf_counter() # Замеряем время до отработки функции lst = [i for i in range(100) if i % 2 == 0] print(time.perf_counter() - start) # Считаем, за сколько отработала функция return lst
@nilmulyashov7274
@nilmulyashov7274 2 жыл бұрын
Но при такой записи мы нарушим принцип единой ответственности функций и принцип DRY. Вынесем всю логику со временем в отдельную функцию. Получится вот это: import time def wrapper(func): start = time.perf_counter() # Замеряем время до отработки функции res = func() print(time.perf_counter() - start) # Считаем, за сколько отработала функция return res def list_by_cycle(): lst = [] for i in range(100): if i % 2 == 0: lst.append(i) return lst def list_comprehension(): lst = [i for i in range(100) if i % 2 == 0] return lst Тогда мы сможем обернуть наши функции в функцию wrapper вот так: # распечатает только время работы функций wrapper(list_by_cycle) wrapper(list_comprehension) # либо так: # распечатает время работы функций и сам сгенерированный список print(wrapper(list_by_cycle)) print(wrapper(list_comprehension))
@nilmulyashov7274
@nilmulyashov7274 2 жыл бұрын
Пока все ок. Так можно. НО! Что если у функций теперь появятся аргументы? Допустим, я хочу сам задавать диапазон в range. Тогда код функций будет выглядеть вот так: def list_by_cycle(n): lst = [] for i in range(n): if i % 2 == 0: lst.append(i) return lst def list_comprehension(n): lst = [i for i in range(n) if i % 2 == 0] return lst Как быть с функцией wrapper? Ну, сходу напрашивается вот такой вариант (причем, в общем случае придется написать **kwargs вместо n): def wrapper(func, n): start = time.perf_counter() # Замеряем время до отработки функции res = func(n) print(time.perf_counter() - start) # Считаем, за сколько отработала функция return res Поэтому, когда будем делать обертку (т.е. при вызове wrapper), придется передавать туда дополнительный аргумент, и будет уже вот это: # распечатает только время работы функций wrapper(list_by_cycle, n=100) wrapper(list_comprehension, n=100) # либо так: # распечатает время работы функций и сам сгенерированный список print(wrapper(list_by_cycle, n=100)) print(wrapper(list_comprehension, n=100))
@nilmulyashov7274
@nilmulyashov7274 2 жыл бұрын
А теперь, что если мы захотим сохранять сгенерированные списки в переменные? Можно сделать так: list_by_cycle_r100 = wrapper(list_by_cycle, n=100) list_comprehension_r100 = wrapper(list_comprehension, n=100) А теперь, что если мне нужно несколько списков в разных диапазонах? Как поступим? Если в лоб делать, то получится вот это: list_by_cycle_r100 = wrapper(list_by_cycle, n=100) list_comprehension_r100 = wrapper(list_comprehension, n=100) list_by_cycle_r1000 = wrapper(list_by_cycle, n=1000) list_comprehension_r1000 = wrapper(list_comprehension, n=1000) list_by_cycle_r10000 = wrapper(list_by_cycle, n=10000) list_comprehension_r10000 = wrapper(list_comprehension, n=10000) Что в итоге-то? Для каждого нового диапазона приходится постоянно оборачивать целевую функцию (т.е. постоянно вызывать wrapper, опять нарушение принципа DRY) и плодить новые переменные. Было бы гораздо удобнее, если бы был синтаксис, позволяющий написать сразу вот так (формируем идеальный конечный результат, так сказать): list_by_cycle_r100 = list_by_cycle(n=100) list_by_cycle_r1000 = list_by_cycle(n=1000) list_by_cycle_r10000 = list_by_cycle(n=10000) Т.е. чтоб функция работала, как и раньше, но при этом еще и время считалось. Было бы вообще здорово. При этом код целевых функций не меняем - помним про принцип единой ответственности. Что ж, на ум приходит вот такая реализация (обратите внимание - мы хотим вызвать wrapper лишь один раз в самом начале): list_by_cycle = wrapper(list_by_cycle) list_comprehension = wrapper(list_comprehension)
@user-qk3ey6tb1k
@user-qk3ey6tb1k 2 жыл бұрын
неужели темная тема
@gore_ot_uma166
@gore_ot_uma166 2 жыл бұрын
а есть декоратор, который удаляет все декораторы с какой-либо декорированной функции? ведь не всегда нужен функционал декоратора
@selfedu_rus
@selfedu_rus 2 жыл бұрын
оставляете ссылку на прежнюю функцию, а декоратор на другую переменную, когда она будет не нужна, то сборщик мусора автоматически удалит декоратор, а функция останется как была
@gore_ot_uma166
@gore_ot_uma166 2 жыл бұрын
Не понял, как это сделать? Есть код: @декоратор Def Функция(): pass Как вызвать эту функцию без декоратора, если он нам в данный момент не нужен?
@selfedu_rus
@selfedu_rus 2 жыл бұрын
@@gore_ot_uma166 так вы декоратор применяйте через функцию: a = декоратор(Функция)
@gore_ot_uma166
@gore_ot_uma166 2 жыл бұрын
Спасибо, тоже думал про этот вариант.
@user-el1fy2ob4d
@user-el1fy2ob4d Жыл бұрын
Не совсем понимаю, для чего вообще внутри func_decorator объявляется еще функция wrapper. Почему нельзя просто в func_decorator: что-то делаем до, func(), что-то делаем после
@selfedu_rus
@selfedu_rus Жыл бұрын
wrapper как раз и подменяет прежнюю функцию, добавляя некоторый функционал, без этого декораторы в принципе не работали бы (или было бы просто вызов одной функции через другую в лоб, передавая каждый раз ссылку на функцию + аргументы)
@user-el1fy2ob4d
@user-el1fy2ob4d Жыл бұрын
@@selfedu_rus Спасибо. Кажется немного поняла, посмотрев еще следующее видео.
@ney107-iz6xl
@ney107-iz6xl 8 ай бұрын
Я декораторы и замыкания понял Тому кто не понял пересмотрите материал возобновите в голове и вернитесь сюда я конечно не весь материал а то что чуть-чуть не поняли или забыли
@user-rq2ob4is5e
@user-rq2ob4is5e Жыл бұрын
А зачем делать вложенную функцию?? в чем разница такого кода и def func1(func): делаем что то перд func func() делаем что то после func
@selfedu_rus
@selfedu_rus Жыл бұрын
А как вы этой функции будете передавать аргументы? Каждый раз вызывать func1 с первым параметром func? Это не очень красивое решение.
@mrpjetrov378
@mrpjetrov378 Жыл бұрын
Всем пока, я на завод
@user-kf7hv6nm2s
@user-kf7hv6nm2s 9 ай бұрын
Этот учитель не понятно объясняет, замудренным языком,Я не понимаю что вы от него так балдеете, может мусолин постоянно
@olegbaskakov3399
@olegbaskakov3399 2 жыл бұрын
Непонятно, зачем нужен wrapper, если и без него весь код можно поместить в func_decorator(func) и вызывать ее самостоятельно.
@selfedu_rus
@selfedu_rus 2 жыл бұрын
вы тогда не сможете декорировать разные функции
@user-du8yk6eh5u
@user-du8yk6eh5u 2 жыл бұрын
@@selfedu_rus Сергей, я извиняюсь, но всё равно не понятно - в примере функция test_time вызывается последовательно для медленного алгоритма и для быстрого. Если бы у test_time не было wrapper и весь код по замеру времени был написан непосредственно в test_time то все будет работать аналогично. Я проверил) Поэтому смысл wrapper не понятен.
@nilmulyashov7274
@nilmulyashov7274 2 жыл бұрын
Я тоже задался этим вопросом. Ответил выше.
@PavelNebo
@PavelNebo Жыл бұрын
Я посмотрел с десяток разных объяснений декораторов, но только сейчас я по-настоящему понял эту тему. Далеко не у каждого человека есть талант преподавателя, именно этот талант позволяет правильно ПРЕПОДАТЬ материал, чтобы он был понятен. Спасибо Вам, Сергей !
@mrpjetrov378
@mrpjetrov378 Жыл бұрын
Что же у других тогда....
@tbassir9076
@tbassir9076 Жыл бұрын
Да, сложновато, но понятно, особенно в конце. Вы всё разложили по полочкам, а в конечном итоге главное оказалось @test_time
@gayratsaidakhmedov5451
@gayratsaidakhmedov5451 6 ай бұрын
спасибо
Children deceived dad #comedy
00:19
yuzvikii_family
Рет қаралды 6 МЛН
Операции над событиями на кругах Эйлера
2:19
Ирина Токмакова
Рет қаралды 2,7 М.
Что такое SQL?
7:11
Merion Academy
Рет қаралды 300 М.
Уроки Python casts #6 - Декораторы
19:50
Oleg Molchanov
Рет қаралды 141 М.