Посмотрел сначала видео Гоши Дударя. Ничерта не понял. Потом посмотрел ваше видео - разница в преподавании колоссальна! Вы просто безупречно, на простых примерах, объясняете тему, спасибо вам!
учил о декораторах на другом канале. Думал даже, что понял суть. Но сейчас проходя заново курс "ООП простыми словами" начинаю усваивать вопросы гораздо глубже.
Я посмотрел с десяток разных объяснений декораторов, но только сейчас я по-настоящему понял эту тему. Далеко не у каждого человека есть талант преподавателя, именно этот талант позволяет правильно ПРЕПОДАТЬ материал, чтобы он был понятен. Спасибо Вам, Сергей !
Сперва смотрел прошлый вариант видео (от 16 мар. 2020) и там к середине мозги начали заворачиваться, я несколько раз на паузу ставил, отматывал, потом просто досмотрел с чувством "пока рановато, позже обязательно раскурю". А здесь всё с ходу понятно! Декоратор был написан буквально "с полпинка", сижу довольный как слон )) Новая подача зашла шикарно, спасибо огромное!
Сергей, спасибо! Курс крутой, возможно когда-нибудь дойдем до асинхронности в Python, был бы рад послушать и изучить в вашей интерпретации информацию про asyncio и т.д.
Да так не то до асинхронности можно дойти, но и до паттернов проектирования на питоне :) Ме, например, очень нравился всегда C#, учить я его пытался в основном самостоятельно (были курсы, но неудачные). Но по сравнению с C# питон заходит намного быстрее. Думаю, дело в преподавателе
Спасибо, у Вас дар! Видел много курсов, так ясно, наглядно и без лишнего усложнения не объясняет никто на русском. Всего Вам наилучшего, 100500+ в карму =) Это касается всех курсов которые здесь размещены.
Я тут цикл для себя написал, рекомендую ознакомиться. while ' Сергей выкладывает видео ': like += 1 comment += 1 print('Спасибо Сергей') else: print('Ждем новое видео')
@@krab9241 да , такое условие есть только у Пайтона. (после цикла можно поставить else) Но сам Гвидо говорил, если бы он заново начал делать Python, то не стал бы делать такое условие.
Едрён батон! Не один год работал с декораторами (которые художники), и только под конец видео поняв, что такое декораторы в питоне, на меня снизашло озарение, почему они названы так. Думаю если бы раньше связал два этих одинаковых слова, быстрее бы понял суть декорирования в питоне (считай ретушевание/корректировка/украшение фукнции). Вообще сильно помогла ссылка на Замыкания. Без замыканий реально было трудно понять суть и смысл. Спасибо.
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)) Нахождение НОД рекурсивно) Чтобы не забывать!
Доброго времени суток, Сергей, заметил, что при задании функции 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 они просто поменяются местами)
Как я пожалел что не начинал смотреть на начальном этапе ваши курсы по базе и пока я смотрел ваш курс ооп, я не особо понимал как работают декораторы, но дойдя до сюда, я пиздец как понял
Видимо всех замыкает на замыканиях)), но объяснение лучше чем у Била Любановича. Например меня заклинило на "КАААК можно передавать функции второе значение, когда ей уже раньше передали значение)) ПОЧЕМУ она его принимает". Видимо нужно еще раз перечитать вложенные функции)). Да и в принципе selfedu классно сделал, что показал, почему замыкание называется замыканием. Сразу практически все стало понятно. Еще стало понятно, что хочу поучить Фласк у selfedu
Урок супер! Всё предельно понятно и примеры хорошие. Спасибо! P.S. Интересно почему при первом вызове декарируемой функции get_nod время вывелось 0,0329.. сек, а не 0,0269 сек, как в последствии и перед этим))
Сергей, я правильно понял, что на практике назначение декорирующей функции это расширение возможностей функции, которую мы декорируем т.е. some_func, не трогая саму функцию? И как тогда с помощью декорирующей функции поменять, к примеру, переменную которая находится в функции some_func?
Да, все верно. Набор параметров декорируемой функции, как правило, остается неизменным, но если хотите что то поменять, то прописывайте у def wrapper() это у будет набор параметров после декорирования.
Спасибо большое, все вполне понятно. Я только не поняла, зачем в принципе нужны декораторы. Ну нельзя ли что-то делать, потом вызывать функцию, потом снова что-то делать?
Как всё работает понятно. Но зачем нужен wrapper? Если этот же код прописать во внешней функции test_time всё будет работать точно также. Каким образом используется замыкание?
Ютуб не пропускает слишком большой коммент, так что буду частями) К примеру, у нас есть вот такие функции: 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
Но при такой записи мы нарушим принцип единой ответственности функций и принцип 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))
Пока все ок. Так можно. НО! Что если у функций теперь появятся аргументы? Допустим, я хочу сам задавать диапазон в 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))
А теперь, что если мы захотим сохранять сгенерированные списки в переменные? Можно сделать так: 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)
Не совсем понимаю, для чего вообще внутри func_decorator объявляется еще функция wrapper. Почему нельзя просто в func_decorator: что-то делаем до, func(), что-то делаем после
wrapper как раз и подменяет прежнюю функцию, добавляя некоторый функционал, без этого декораторы в принципе не работали бы (или было бы просто вызов одной функции через другую в лоб, передавая каждый раз ссылку на функцию + аргументы)
Я декораторы и замыкания понял Тому кто не понял пересмотрите материал возобновите в голове и вернитесь сюда я конечно не весь материал а то что чуть-чуть не поняли или забыли
оставляете ссылку на прежнюю функцию, а декоратор на другую переменную, когда она будет не нужна, то сборщик мусора автоматически удалит декоратор, а функция останется как была
вы создаете функцию и потом используете ее как декоратор. Но когда мы не создаем ? когда на видео кто то просто пишет декоратор ( будто все знают что он делает ) . Это и отпугивает . Почему никто не понимает что когда пишешь декоратор не догадываешся что никто не знает откуда ты его взял и как узнать что он делает. Но когда ты создал его сам и декорировал какую то функцию это и ОСЕЛ поймет. И мне кажется даже этот прямой намек ни этот канал ни следующие не поймут.
@@selfedu_rus Сергей, я извиняюсь, но всё равно не понятно - в примере функция test_time вызывается последовательно для медленного алгоритма и для быстрого. Если бы у test_time не было wrapper и весь код по замеру времени был написан непосредственно в test_time то все будет работать аналогично. Я проверил) Поэтому смысл wrapper не понятен.
Посмотрел сначала видео Гоши Дударя. Ничерта не понял. Потом посмотрел ваше видео - разница в преподавании колоссальна! Вы просто безупречно, на простых примерах, объясняете тему, спасибо вам!
@@nikitaaspaev1638 гоша идиот. Сам себе объясняет
Гоша и сам ничего не понимает)
selfedu
*Благодаря замыканию, у меня аж мозг замкнуло! Как это все запутано, 7 раз пересмотрел! Спасибо Сергей без вас не разобрался бы!*
Как-же вы всё прекрасно разжевали нам, за несколько жалких минут понял то, что не понимал в течении месяца.
*чувства искренней благодарности*
с четвёртого раза нашёл ролик, который понятно простым языком объясняет, что такое декораторы, спасибо!
учил о декораторах на другом канале. Думал даже, что понял суть. Но сейчас проходя заново курс "ООП простыми словами" начинаю усваивать вопросы гораздо глубже.
Я посмотрел с десяток разных объяснений декораторов, но только сейчас я по-настоящему понял эту тему.
Далеко не у каждого человека есть талант преподавателя, именно этот талант позволяет правильно ПРЕПОДАТЬ материал, чтобы он был понятен.
Спасибо Вам, Сергей !
Что же у других тогда....
Не неси чушь.
Спасибо огромное, автор. Единственный, кто подробно всё объяснил.
@PythonRussian - объясняет просто "жесть", вообще МОЛОДЕЦ парнишка!Посмотри не прогадаешь - объясняет может даже лучьше
Благодарю вас за обучение! Вы очень внимательный и ответственный учитель. Здоровья Вам и Вашим близким
Сперва смотрел прошлый вариант видео (от 16 мар. 2020) и там к середине мозги начали заворачиваться, я несколько раз на паузу ставил, отматывал, потом просто досмотрел с чувством "пока рановато, позже обязательно раскурю". А здесь всё с ходу понятно! Декоратор был написан буквально "с полпинка", сижу довольный как слон )) Новая подача зашла шикарно, спасибо огромное!
Понятно, просто, доходчиво... вообщек как и все остальные уроку Сергея. Огромное спасибо за вашу работу!
пожалуй это самая сложная тема после рекурсии, с вашими уроками хоть как-то начал ее понимать)
Все очень понятно изложено, спасибо! Теперь не понимаю, как я могла этого не понимать))
Сергей, спасибо! Курс крутой, возможно когда-нибудь дойдем до асинхронности в Python, был бы рад послушать и изучить в вашей интерпретации информацию про asyncio и т.д.
Да так не то до асинхронности можно дойти, но и до паттернов проектирования на питоне :) Ме, например, очень нравился всегда C#, учить я его пытался в основном самостоятельно (были курсы, но неудачные). Но по сравнению с C# питон заходит намного быстрее. Думаю, дело в преподавателе
Хоть и понял со 2 раза, но материал понятен
Огромное спасибо автору!
пришла по рекомендации из какого-то комментария ) и не пожалела , спасибо за ваше объяснений ! Развития вашему каналу🍀
просто идеальное объяснение, спасибо вам большое)
Спасибо, это единственное видео где я все понял. Смотрел других, пересматривал по 3 раза но не понял. Большое спасибо автору!
Отличное описание, автору спасибо!
Спасибо, у Вас дар! Видел много курсов, так ясно, наглядно и без лишнего усложнения не объясняет никто на русском. Всего Вам наилучшего, 100500+ в карму =) Это касается всех курсов которые здесь размещены.
Спасибо большое вам, очень ценные уроки😊
Лучшие объяснения из тех что я видел, хотя я давно пишу на питоне, но именно изучить его захотелось сейчас
Я тут цикл для себя написал, рекомендую ознакомиться.
while ' Сергей выкладывает видео ':
like += 1
comment += 1
print('Спасибо Сергей')
else:
print('Ждем новое видео')
пока иначе. а так можно было!?
@@krab9241 да , такое условие есть только у Пайтона. (после цикла можно поставить else)
Но сам Гвидо говорил, если бы он заново начал делать Python, то не стал бы делать такое условие.
@@likeclockwork9600 'else' в 'while' используется в комбинации с 'break', иначе в 'else' нет смысла...
Поздравляю вас с говнокодом!
Создал бесконечный цикл. И зачем то увеличивал переменные like и comment
@@novichok3417 +
Супер, не знаю кто еще лучше может настолько понятно объяснить. Спасибо тебе большое)
@PythonRussian - объясняет просто "жесть", вообще МОЛОДЕЦ парнишка!
Едрён батон! Не один год работал с декораторами (которые художники), и только под конец видео поняв, что такое декораторы в питоне, на меня снизашло озарение, почему они названы так. Думаю если бы раньше связал два этих одинаковых слова, быстрее бы понял суть декорирования в питоне (считай ретушевание/корректировка/украшение фукнции). Вообще сильно помогла ссылка на Замыкания. Без замыканий реально было трудно понять суть и смысл. Спасибо.
Коммент в поддержку канала!)
Ура! Декораторы! А ведь именно на этой теме я засыпался на первом собеседовании) маст хев! Спасибо за короткое и понятное видео, Сергей!
Сэр, Вы серьёзно? Не зная декораторов уже можно идти на собеседование?? Я думал это самое начало обучения...
@@ИгорьВоронов-ъ4м собеседование это в том числе опыт, не попробуешь не узнаешь.
Спасибо, отлиная лекция
Очень крутая подача, лучше ещё не видел!
Огромное спасибо за урок!
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))
Нахождение НОД рекурсивно) Чтобы не забывать!
Спасибо! Очень подробно и простым языком, а главное понятно!
спасибо большое было очень полезно 🥰🥰🥰
Спасибо. Великолепно. Я понял.
Доброго времени суток, Сергей, заметил, что при задании функции 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 они просто поменяются местами)
мега круть про декораторы
Как я пожалел что не начинал смотреть на начальном этапе ваши курсы по базе и пока я смотрел ваш курс ооп, я не особо понимал как работают декораторы, но дойдя до сюда, я пиздец как понял
спасибо!👏👍
Спасибо!
Я понял это намек, я все ловлю на лету... Но чета я совсем... ... Бллагодаря Вам, все лучше :)
Доброго времени суток. Спасибо за видео. Вопрос: могу ли я "продекорировать" функцию функцией-декоратором, в которой не замыкания?
спасибо
Legend
Спасибо! Суппер!
Спасибо,Сергей! Видео понятное,но всё же пример с алгоритмом Евклида может запутать!
Видимо всех замыкает на замыканиях)), но объяснение лучше чем у Била Любановича. Например меня заклинило на "КАААК можно передавать функции второе значение, когда ей уже раньше передали значение)) ПОЧЕМУ она его принимает". Видимо нужно еще раз перечитать вложенные функции)). Да и в принципе selfedu классно сделал, что показал, почему замыкание называется замыканием. Сразу практически все стало понятно. Еще стало понятно, что хочу поучить Фласк у selfedu
Урок супер! Всё предельно понятно и примеры хорошие. Спасибо!
P.S. Интересно почему при первом вызове декарируемой функции get_nod время вывелось 0,0329.. сек, а не 0,0269 сек, как в последствии и перед этим))
ОС Windows (скорее всего она у вас) - это не система реального времени и программы могут выполняться с разной скоростью
Сергей, я правильно понял, что на практике назначение декорирующей функции это расширение возможностей функции, которую мы декорируем т.е. some_func, не трогая саму функцию?
И как тогда с помощью декорирующей функции поменять, к примеру, переменную которая находится в функции some_func?
Да, все верно. Набор параметров декорируемой функции, как правило, остается неизменным, но если хотите что то поменять, то прописывайте у def wrapper() это у будет набор параметров после декорирования.
Спасибо большое, все вполне понятно. Я только не поняла, зачем в принципе нужны декораторы. Ну нельзя ли что-то делать, потом вызывать функцию, потом снова что-то делать?
во фреймворках они везде и всюду )) очень удобная штука, с практикой усвоите этот момент
👍
Я не понял почему нужно в wrapper тоже прописывать параметр title.. (Если не использовать args)
Подскажите пожалуйста, на Stepik у вас листинги кода прилагаются? И что там дополнительно есть?
дополнительно только практика
👍👍👍👍👍
Видео за 13 минут, разбираюсь что происходит три часа((
Что по поводу __name__ и __doc__ при использовании нескольких декораторов?
да все то же самое, так где декорирование функции происходит, сохраняем __name__ и __doc__
Как всё работает понятно. Но зачем нужен wrapper? Если этот же код прописать во внешней функции test_time всё будет работать точно также. Каким образом используется замыкание?
вы тогда не сможете передавать аргументы функции (без wrapper), точнее передать только один раз
Ютуб не пропускает слишком большой коммент, так что буду частями)
К примеру, у нас есть вот такие функции:
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
Но при такой записи мы нарушим принцип единой ответственности функций и принцип 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))
Пока все ок. Так можно. НО! Что если у функций теперь появятся аргументы? Допустим, я хочу сам задавать диапазон в 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))
А теперь, что если мы захотим сохранять сгенерированные списки в переменные? Можно сделать так:
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)
Если в классе есть setter для __old, то не разумно ли в методе __init__ прописать self.old = old вместо self.__old = old
да, разумно!
@@selfedu_rus перепутал тему. хотел спросить в ua-cam.com/video/MxviMwbGl3I/v-deo.html&feature=share&EKLEiJECCKjOmKnC5IiRIQ
неужели темная тема
Этот учитель не понятно объясняет, замудренным языком,Я не понимаю что вы от него так балдеете, может мусолин постоянно
Если последовательно смотреть, то всё понятно. Это не замудрённый язык
Не совсем понимаю, для чего вообще внутри func_decorator объявляется еще функция wrapper. Почему нельзя просто в func_decorator: что-то делаем до, func(), что-то делаем после
wrapper как раз и подменяет прежнюю функцию, добавляя некоторый функционал, без этого декораторы в принципе не работали бы (или было бы просто вызов одной функции через другую в лоб, передавая каждый раз ссылку на функцию + аргументы)
@@selfedu_rus Спасибо. Кажется немного поняла, посмотрев еще следующее видео.
Всем пока, я на завод
Я декораторы и замыкания понял
Тому кто не понял пересмотрите материал возобновите в голове и вернитесь сюда я конечно не весь материал а то что чуть-чуть не поняли или забыли
а есть декоратор, который удаляет все декораторы с какой-либо декорированной функции? ведь не всегда нужен функционал декоратора
оставляете ссылку на прежнюю функцию, а декоратор на другую переменную, когда она будет не нужна, то сборщик мусора автоматически удалит декоратор, а функция останется как была
Не понял, как это сделать?
Есть код:
@декоратор
Def Функция():
pass
Как вызвать эту функцию без декоратора, если он нам в данный момент не нужен?
@@gore_ot_uma166 так вы декоратор применяйте через функцию:
a = декоратор(Функция)
Спасибо, тоже думал про этот вариант.
вы создаете функцию и потом используете ее как декоратор. Но когда мы не создаем ? когда на видео кто то просто пишет декоратор ( будто все знают что он делает ) . Это и отпугивает . Почему никто не понимает что когда пишешь декоратор не догадываешся что никто не знает откуда ты его взял и как узнать что он делает. Но когда ты создал его сам и декорировал какую то функцию это и ОСЕЛ поймет. И мне кажется даже этот прямой намек ни этот канал ни следующие не поймут.
А зачем делать вложенную функцию?? в чем разница такого кода и
def func1(func):
делаем что то перд func
func()
делаем что то после func
А как вы этой функции будете передавать аргументы? Каждый раз вызывать func1 с первым параметром func? Это не очень красивое решение.
Непонятно, зачем нужен wrapper, если и без него весь код можно поместить в func_decorator(func) и вызывать ее самостоятельно.
вы тогда не сможете декорировать разные функции
@@selfedu_rus Сергей, я извиняюсь, но всё равно не понятно - в примере функция test_time вызывается последовательно для медленного алгоритма и для быстрого. Если бы у test_time не было wrapper и весь код по замеру времени был написан непосредственно в test_time то все будет работать аналогично. Я проверил) Поэтому смысл wrapper не понятен.
Я тоже задался этим вопросом. Ответил выше.
Хоть бы пример нормальный привёл, а не из какой-то зарубежной горе-книги/статьи.
Да, сложновато, но понятно, особенно в конце. Вы всё разложили по полочкам, а в конечном итоге главное оказалось @test_time
Спасибо
спасибо