Мне 63. Хотел учиться веб-дизайну, но через год понял, что до заработка мой левел в этой жизни уже не поднимется. Теперь занимаюсь чисто для борьбы с альт-геймером ) Так вот, как раз вчера, преодолевая невероятное сопротивление нейронов, заставил их законтачить на понятии Декоратора. На эту СОБАКУ (@) у меня ушёл весь день! А сегодня, слушая Ваше изложение, удивлялся тому, что можно сложные вещи объяснить ПРОСТО! У Вас - БЕЗУПРЕЧНОЕ изложение материала. Я даже не помню, когда я так радовался речи преподавателя!! Грейт грейтфул Вам !! ))
@zaemiel5 жыл бұрын
Спасибо большое. Очень рад, что мой контент вам помог
@АйратКаримов-м3п4 жыл бұрын
Не боись дед! Все получится! И в 73 года учатся и устраиваются прогерами. А раз уж ты тут(на ютубе) , загугли про это и все поймешь
@driewtonmai4 жыл бұрын
Мое уважение.
@vagifk28644 жыл бұрын
Дерзайте. Мой папа в 70 лет программировать научился ! На Visual basic
@maskanews4 жыл бұрын
@@zaemiel а получается def timeit это обычная функция? И выходит любую функцию можно вызвать собакой? Или что-то делает def timeit не функцией, а именно декоратором?
@olgaponomarenko5084 Жыл бұрын
Удивительно ! Лучшее объяснение, которое я встречала, у вас талант объяснять, спасибо)
@Python_in_UA2 жыл бұрын
Дякую. Світлий розум і відкрите серце дають вам змогу бути гарним вчителем. Це рідкісний дар.
@simurgh3143 жыл бұрын
Порадовал ход твоих мыслей. Люблю когда мысли хронологично опираются друг на друга, создавая правильную логичную последовательность, без темных кусков и взятых неоткуда сущностей. СПАСИБО тебе, амиго, ты один из лучших.
@artemlevin8982 Жыл бұрын
я не понимал,что такое декоративы, но с помощью тебя я понял все. Спасибо!
@Russia-Infinity Жыл бұрын
Автору огромное спасибо, вот сейчас стало понятно крайне доходчиво, зачем нужны Декораторы, чтобы не было лишнего кода помимо основного кода в теле функции!!
@valeriivolkov_ua3 жыл бұрын
Там в конце было сказано: "если понравилось - подписывайтесь на канал и ставьте лайки". Понравилось? Да это не то слово! Я в восторге просто! Большое спасибо!
@АндрейИнвентор2 жыл бұрын
Спасибо за понятное объяснение на пальцах!
@andreyolshansky8078 Жыл бұрын
Самое Доходчивое объяснение материала!
@Пранкадемия3 жыл бұрын
Спасибо! Приятно когда объясняет тему не просто человек который знает сам, но и который именно умеет объяснять! Редкость!
@JeDesi Жыл бұрын
Олег, спасибо огромное за такое разжевывание темы. Ты такие моменты затрагиваешь, которые непонятны интуитивно при изучении, да и к тому, их и сформулировать как вопрос сложно. А ты это объясняешь всё...Респект тебе!
@ВладимирДолгополов-ц5ф2 жыл бұрын
Три дня разбираюсь с декораторами. И только из этого видео понял, что это за зверь!)
@artem_ik-r6s5 жыл бұрын
Олег, как же приятно Вас слушать. Объяснение выше всяких похвал!
@zolotaya_pora10 ай бұрын
лучшее объяснение про декораторы!
@thesergeymen26326 жыл бұрын
Вот это годнота. Я и до этого с декораторами работал, но не понимал их применение и использовал чуть по-другому.
@askorytin-tq4fl6 жыл бұрын
Как вариант, более короткая форма для парных чисел используя range: >>> l = [x for x in range(2,100,2)] >>> print(l) [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
@Фанатик-к5т4 жыл бұрын
или l = [x*2 for x in range(1, 500)]
@triceratropical28652 жыл бұрын
Здесь я думаю специально "поддали нагрузки", проводя сравнения остатка с нулем.
@victorstepanov35882 жыл бұрын
Да, этот алгоритм покруче
@ChikivaraTV5 жыл бұрын
Бог программирования, спасибо большое, за доступное и наглядное объяснение!
@BloodGraber5 жыл бұрын
Все грамотно и информативно разложено по полочкам. Большое спасибо за Ваш труд!
@nocomments90612 жыл бұрын
Объяснение - огнище. А то один и тот же пример у большинства - с числами Фибоначчи. На кой черт мне городить огород ради такого, где мне в реальности использовать? А тут все объяснения "реального мира": нарушает принципы dry и единой ответственности, да ещё и объяснение без использования сахара. Короче, от души!
@коньвпальто-ч6у3 жыл бұрын
Спасибо, наконец я понял как они работают и для чего нужны эти декораторы 👍
@ivanbag97414 жыл бұрын
Отличное изложение! Пример то что надо! Смотрел другие видосы про декораторы, читал. На таких кривых примерах объяснялось всё, что не понятно было для чего городить огород. Спасибо!
@melancholic_017 Жыл бұрын
Мужик, я бы тебе дал) Заплатил бабки за курс, а учат меня такие интузиасты как ты, спасибо!
@chalex2k2 жыл бұрын
0:20 пример, в котором следует использовать декораторы 7:21 о функциях как объектах 7:58 декоратор функции, не принимающей аргументы 10:46 добавление аргументов в функцию 12:07 как работает синтаксический сахар @decorator 15:49 добавление аргументов декоратора
@diamagnetic262 жыл бұрын
Спасибо вам, самый доступный подход к объяснению!
@МартовСергей-й3я Жыл бұрын
Очень внятное и доступное объяснение роли декораторов! Жаль, что Вас на степике нет.
@eugenkirya94763 жыл бұрын
Капец!!! перелопатил кучу документации - не понял... тут за 15 мин всё ясно!!! СПС
@denisden62224 жыл бұрын
Поскольку l1 = результат ВЫПОЛНЕНИЯ функции timeit, а результат выполнения этой функции = return wrapper, то в итоге, l1 = wrapper (то, что вернуло выполнение функции timeit). Спасибо за это пояснение! Никак не мог понять почему так происходит)
@vladimirkulakov61263 жыл бұрын
Спасибо Олег! Ваши видео очень полезны для расширения понимания материала
@sda15643 жыл бұрын
Привет! Всегда воспринимал декораторы как нечто сложное, но благодаря тебе с легкостью разобрался Огромное спасибо за этот урок и все остальные!
@ispan4eG4 жыл бұрын
я в шоке! Наконец-то понял как это работает! Такого простого объяснения я не ожидал. Спасибо!
@vladimirkulakov86673 жыл бұрын
Шикарная демонстрация замыканий, огромный респект! и Вот я уже на декораторах)
@tier61wro11 ай бұрын
Спасибо большое за контент, единствеенное, если заглянуть глубоко получается, что декораторы это частные случаи замыканий. Возможно стоило сначала рассказать о замыканиях а потом уже о декораторах.
@MrCher6664 жыл бұрын
ПФ ... Мужик.... Здоровья тебе, хахаха, ибо я столько стучался, что бы понять как работает декоратор, а ты нормально объяснил всё на адекватных примерах. Спасибо огромное
@artemmozorow79023 жыл бұрын
Благодарю, все довольно кратко и понятно.
@deceivedxchild4 жыл бұрын
Из двух других видеоуроков с горем пополам понял, что такое декораторы, но совершенно не понял их предназначение - муть какая-то. Уже думал, что на этой теме мои способности иссякают, но погуглил и попал сюда - тут всё понятно сразу же, тк что это не у меня способности иссякают, а спсобность объяснять - у тех преподов, которых смотрел. Большое спасибо!
@loktionov3 жыл бұрын
Олег, спасибо, очень понятно объясняешь
@vovaysach3 жыл бұрын
Спасибо большое! очень понятно, а то читал в паре мест, смотрел в курсах - там плохо было рассказано.
@lefort69433 жыл бұрын
Спасибо Олег, вы лучший преподаватель!
@vladyslavpaliasnyi16113 жыл бұрын
Отличное и доступное обьяснение. Спасибо!
@DavidHill19806 жыл бұрын
Oleg восхищаюсь упорством… не прекращай создавать контент
@nestenerusnester47986 жыл бұрын
Расскажи про yeild и магические методы
@Dennis_Ritchie Жыл бұрын
офигенный пример с datetime
@timtimbot6 жыл бұрын
Один из самых полезных каналов
@EvgenySigvald6 жыл бұрын
Занятный момент - код внутри декоратора на самом верхнем уровне будет выполнен всегда, при инициализации декорируемой функции (на чём собственно и основана работа маршрутизатора упомянутого Flask), это видно при запуске скрипта - вызовов функций нет, но вывод идёт. Было бы здорово акцентировать на этом внимание и дополнить примерами использования. Может даже на отдельный выпуск хватить ) PS: Я ещё не всё посмотрел, может это в другом видео есть, но вдруг )
@zaemiel6 жыл бұрын
нет, я на этом не акцентировался. Наверное, действительно следовало об этом сказать...
@suhanoves4 жыл бұрын
Для тех кто столкнулся с подобным вопросом, но самостоятельно не может найти на него ответа, вот отличная статья на хабре habr.com/ru/post/141501/
@АртемЖучков-з4д4 жыл бұрын
Олег, спасибо! Теперь то все понятно наконец =) Я уже не первый десяток видео про декораторы смотрю, твое будет последним, ибо после него вопросов не остается совсем)
@uniqqquniqqq20532 жыл бұрын
Отличное объяснение, спасибо вам
@rubickaghanimus44234 жыл бұрын
Спасибо ваша лекция сильно помогла!
@ПростоУлыбка-ш2о6 жыл бұрын
_Олег, привет. У тебя замечательные уроки получаются. Очень толково и грамотно объясняешь. А не планируешь ли ты записать полноценный обучающий курс по Python? Прям чтоб с азов (для начинающих) до вершин мастерства?_
@yanagaeify6 жыл бұрын
Можешь воспользоваться этими курсами: этот для начала stepik.org/course/67 этот сложнее stepik.org/course/512 этот самый сложный stepik.org/course/1280
@Alex-yx2ye6 жыл бұрын
Поддерживаю на все 100%
@ПростоУлыбка-ш2о6 жыл бұрын
_спасибо за ссылки, Марк, но этих ребят я не знаю, а вот Олег себя отлично поставил. Потому и обращаюсь к нему_
@JohnChrom6 жыл бұрын
Роман Белов присоединяюсь. С удовольствием записался бы.
@callpack965 жыл бұрын
Роман Белов было бы круто
@igorb.49176 жыл бұрын
Спасибо, отличный автор, приятно слушать и смотреть.
@zaemiel6 жыл бұрын
Спасибо
@nordmilk4 жыл бұрын
я 5 лет пытался понять что это, а автор этого урока расказал за 7 минут
@аавыф-б4о3 жыл бұрын
Круто объясняете, всё понятно, спасибо!
@АлександрБирюков-о2л6 жыл бұрын
я бы добавил сюда что для того, чтобы декорируемая функция при вызове __name__ возвращала свое имя, нужно wrapper в свою очередь декорировать @functools.wraps(func) из стандартной библиотеки functools, это не обязательно, но бывает очень полезно например при выводе ошибки или при отладке программы
@predatel_rodini6 жыл бұрын
from flask import session from functools import wraps # standart decorator for selfmade decorators def check_logged_in(func: 'object') -> 'object': @wraps(func) def wrapper(*args, **kwargs): if 'logged_in' in session: return func(*args, **kwargs) return 'You are NOT logged in.' return wrapper
@TahirKabilov6 жыл бұрын
я вообще декораторами записываю трейсбеки в базу с именем фунции всеми аргументами, если интересно сделаю ссылку на код. чтою велосипед не изобретать
@lonterel47045 жыл бұрын
@@TahirKabilov давай
@yerlan21006 жыл бұрын
Спасибо, Олег! Отличные уроки у Вас! Продолжайте в том же духе.
@maxmorgan90256 жыл бұрын
Спасибо, да да и про замыкания. Пожалуйста.
@darksouls7066 жыл бұрын
очень хорошие касты по python! Подписался )
@Gleb_Pastushenko4 жыл бұрын
Здравствуйте. На 15:40, если я всё правильно понял, то это синтаксический сахар не для l1 = timeit(one), а для замены one = timeit(one)? На 17:20 получается, что код между timeit и outer будет выполнен уже на этапе декорирования, т.е. ещё до вызова декорируемой функции? Если да, то не очень понятно для чего это нужно.
@accidiet6 жыл бұрын
шикарная архитектура Python ,,,, ох я счастлив ! Истина со мной
@vitalyvlasenko54953 жыл бұрын
12:00 генератор отработал медленнее) думаю, дело в том, что генератор сразу резервирует место, а при вызове метода append() иногда приходится переносить весь список в новую область памяти.
@7razum5 жыл бұрын
Спасибо. Доступно изложено
@АлексейТаганрогов3 жыл бұрын
Отличный урок. Единственное что я так и не понял - почему в конце урока, когда добавлена функция outer, аргумент name выводится в консоль два раза (команда print в 7-й строке) ? Когда происходит второе обращение к этой функции print ?
@ЕвгенийБутков-ф3к2 жыл бұрын
удалось разобраться?
@He1LBoy345 жыл бұрын
Очень круто! Спасибо за объяснение!
@jvoorhees4 жыл бұрын
Ну не знай на счет скорости, порой происходит обратное. Возможно что-то изменили в Python на 2020 год, может погрешности или прирост только в Linux, но особой разницы не видно, по крайней мере на Windows. Разница колеблется в районе 0:00:00.000010 Вот некоторое количество результатов: one: 0:00:00.001000 two: 0:00:00.000999 ----------------------------------------- one: 0:00:00.001004 two: 0:00:00.000999 ----------------------------------------- one: 0:00:00.001007 two: 0:00:00.000998 ----------------------------------------- one: 0:00:00.000999 two: 0:00:00.000999 ----------------------------------------- one: 0:00:00.000999 two: 0:00:00.001000 Возможно при сильно нагруженных проектах это пройдет, но на легких точно разницы нет. Возможно я чего-то не понимаю. Как много всего возможного в этом сообщении =)
@аавыф-б4о Жыл бұрын
лайк, Олег не сказал только, что вместо 'args' и 'kwargs' мы можем написать любые другие идентификаторы (имена), хоть 'parampam1' и 'parampam2', - это НЕ специмена (или какие-то операторы языка), а просто договорились так называть эти параметры в подобных случаях - а вообще это просто параметры, которые можно назвать как угодно (главное - поставить зведочки '*' и '**"). трудно понять зачем объяснять, тем для кого это ну очень очевидно (тебе), но новичков это реально путает и вымораживает: что такое 'args', что такое 'kwargs' (это особенно страшное слово), и почему они везде. а это просто название от балды двух параметров, и сокращение от фраз 'arguments' и 'keyword arguments'. они прям реально на этом месте запинаются, как минимум, и долго (до полугода) постоянно возвращаются к этому, как максимум. это резко углубит объяснение, в то же время не усложняя его. возможно, ты заострял внимание на этом моменте в каком-то другом ролике
@imgnl6 жыл бұрын
Олег, спасибо большое!
@warmybo6 жыл бұрын
Класс! Все просто и понятно!
@rugineer6 жыл бұрын
Прикольно, что на 11:56 время создания списка через for меньше, чем через генератор. Понятно, что это погрешность, но всё же)
@devZu96 жыл бұрын
Я кстати это тоже заметил. Вообще как только он обернул всё в декоратор, то почему-то скорость у for значительно возросла. А когда он сменил 10**4 на 10000, так вот for ещё и вышел в лидеры по скорости.
@asaki1k3 жыл бұрын
@@devZu9 предполагаю, потому что в цикле 10**4 считалось снова и снова каждую итерацию, а в той конструкции результат запоминался
@leomysky4 жыл бұрын
Круто Круто И ещё раз Круто! Спасибо!
@alinaveter73712 жыл бұрын
Просто обязана отписаться, что разжевано действительно восхитительно, спасибо от всей души!
@microsoft87922 жыл бұрын
а если перед определением функции больше одного декоратора указано?
@Dtankhaev Жыл бұрын
Лучший!
@MAIVSHOW4 жыл бұрын
13:18, можно просто: l1 = one print(l1(10))
@johnwoods9784 жыл бұрын
красава. монстр.
@undefined4223 жыл бұрын
@@johnwoods978 print(one(10)) ПРОСТО МАШИНА
@АрТём-п8к4д3 жыл бұрын
подскажите в чем разницы между import datetime и from datetime import datetime. я думал что импортируя весь модуль я сразу буду иметь доступ ко всем его плюшкам но тут это не прокатило просто импортирую датувремя я не получил метод now а вот импортируя методом фром***импорт*** я получил метод now. странно но у меня оба метода выводятся с одинаковой скорости то есть счетчики показываю стандартно сотую секунды.
@abrosovd Жыл бұрын
11:54 при запуске видно, что второй вызов происходит дольше чем первый :)
@ezez25863 жыл бұрын
а почему при указании func в скобках вызывалась именно функция one, а не two?
@Newyork005 жыл бұрын
Олег, добрый день. Сможете подсказать логику Питона исходя из следующего кода: Код стоит считать бессмысленным. Была просто практика с декораторами. def PlusN(func): def wrapper(n): print('1', n) n += 2 print('2', n) result = func(n) return wrapper @PlusN def CountN(n): print('3', n) print(n ** 2) #CountN(3) wrap = PlusN(CountN) print(wrap) countN = wrap(3) Вопрос в том, что на выходе ответ будет 49. Я понимаю, что питон вызывает 2 раза wrapper. Но при этом только 1 раз CountN. Если декоратор закомментить, то будет ожидаемая цифра 25. Спасибо.
@79fz2707046 жыл бұрын
Олег, Вы говорите не про генераторы, а про list comprehension. Можно создавать генераторы подобным способом, но скобки должны быть круглые, например: g = (x for x in range(10**4) if x % 2 == 0)
@zaemiel6 жыл бұрын
Честно говоря, даже не представляю чем вы слушаете.... Здесь я говорю только о генераторах списков. 0:18 - впервые упоминаю генератор списка 0:36 - уже второе упоминание 0:57 - третье при постановке задачи И минуты не прошло, как генераторы списков были упомянуты мной трижды. Этот скринкаст находится в контексте предыдущего, который и был целиком посвящен генераторам списков - list comprehension. Для удобства Марк сократил в своем коменте упоминание - до генераторов, потому что мы находились в определенном контексте, который нужно учитывать. Об этом я тоже сказал. А так да - то, что вы написали - это генератор.
@79fz2707046 жыл бұрын
Видимо я просто привык к другой терминологии, мне помниться, это называли списковое включение, в вики есть одноименная статья. В любом случае, Вы делаете хорошие уроки, продолжайте в том же духе!
@zaemiel6 жыл бұрын
Спасибо. Прошу прощения за резкость.
@go51906 жыл бұрын
Спасибо!
@edgull_tlt4 жыл бұрын
Спасибище!
@lanalinali5 жыл бұрын
интересно, понятно) спасибо!
@АлександрГайдук-ь8ф5 жыл бұрын
Спасибо. Я понял что такое декораторы
@GoodBoy-hs7pv5 жыл бұрын
Блестяще!!!
@АйратКаримов-м3п4 жыл бұрын
добрый день. Почему нельзя в предпоследний return(который перед return wrapper стоит в функции timeit) вставить func(*args,**kwargs) сразу? Так работает быстрее
@MELkey35 жыл бұрын
Не понял, а как декоратор понял что декорируемую функцию надо было передать в функцию outer? заранее спасибо за ответ
@fffoxed15 жыл бұрын
ни как, он же просто возвращает саму функцию outer
@sweetstranger40293 жыл бұрын
В состоянии кто-нибудь объяснить по какому принципу в декорирующую функцию дальше пробрасываются аргументы изначальной функции ??? Т.е. есть такой пример, допустим : def wrapper(func): def inner(arg): print('Start wrapp') func(arg) print('Wrapp end') return inner def text(arg : str): print('Here is a simple text '+ arg) text = wrapper(text) text('mmm, okay') Переопределяем имя text , в декоратор кидаем объект функции text. Возвращается декоратор, который почему-то принимает просто так "arg". Как именно мы передали arg ?
@Makumazaan4 жыл бұрын
Это не касается данного урока, но в этих конкретных примерах оптимальнее было бы убрать control flow statement используя третий аргумент "step" в функции range. even = [num for num in range(0, 10**4, 2)]
@МаксимСкочко-р6у2 жыл бұрын
А в каком редакторе вы пишите?
@TheIfankill3 жыл бұрын
Не понимаю откуда в функции outer в декораторе, передаётся func. Откуда она взялась? Просто интересно, спасибо
@paveldubov15622 жыл бұрын
в данном случае `func` - название позиционного параметра под которым подразумевается оригинальная функция (`one`), которая подлежит декорированию
@Blowjin2 жыл бұрын
10:02 разница во времени почти исчезла. А какая разница, что быстрее? Часто ли это становится ботлнеком на практике? В целом, очень странно рассуждать о скорости с интерпретируемым ЯП и не на RealTime OS. Сама тема объяснена очень годно, спасибо!
@zaemiel2 жыл бұрын
Вы не на том фиксируетесь. Вообще наплевать на то, что там быстрее. Видео не об этом, а том, как декораторы работают. Остальное - это просто пример, легенда, постановка задачи.
@SmileGobo6 жыл бұрын
А почему после использования декораторов время выполнения с циклом уменьшилось? Кеширование?
@AlexandrSpirit4 жыл бұрын
на 12й секунде, функция two неожиданно стала дольше работать! Тогда как ранее была быстрее чем one. Из-за чего?
@davitkhachatryan51002 жыл бұрын
Ребята есть вопрос: Тоесть если перед опбявление функцией указан декоратор(@), тогда сама функция и функция-декоратора выполняются вместе ?
@paveldubov15622 жыл бұрын
вызывается функция-декоратор в теле которой выполняется вызов функции, над которой указана собака (@)
@herrschwarzfuchs5 жыл бұрын
на 9.42 м. запустил у себя. Получил TypeError: 'list' object is not callable. Когда привел к виду l1 = one l2 = two (без скобок) заработало без ошибок. Вопрос, что это было?
@ralfralfforas67613 жыл бұрын
Сделай шрифт крупнее плохо видно 😀
@timursafin52146 жыл бұрын
Для чего нужна функция wrapper?
@zaemiel6 жыл бұрын
Затем, что у вас не получится обернуть функцию в какой-то код без этой служебной функции. Поэкспериментируйте. Это важно (я имею в виду играться и экспериментировать)
@uawakeme5 жыл бұрын
Не очень понял, в когда и где именно происходит вызов функции wrapper?
@uawakeme5 жыл бұрын
Сам поигрался с кодом и разобрался!
@nikitadenisov1665 жыл бұрын
Но разве функция two генератор. Я просто думал, что это list comprehension. А генератор, это где yeld . Где я не прав?
@zaemiel5 жыл бұрын
а разве я не сказал "Генератор Списка"?
@nikitadenisov1665 жыл бұрын
@@zaemiel извините, наверное не услышал. Честно не ожидал, что вы ответите.
@adginr6 жыл бұрын
Благодрю.
@xurry4988 Жыл бұрын
я пишу в пайчарме и самое смешное это то, что время разное выдает, иногда генератор быстрее, иногда медленее
@esthetik_life6 жыл бұрын
Спасибо за Ваши видео, как всегда всё на высоте ! Не совсем понял, зачем в функцию wrapper вы принимаете *args и **kwargs, ведь если эта функция получить кортеж или словарь, то будет ошибка, или я чего не понимаю ?
@zaemiel6 жыл бұрын
*args и **kwargs - это не просто список или словарь - это позиционные и именованные аргументы. Экспериментируйте и посмотрите, какие аргументы и куда идут на вход...