#12. Магический метод __call__. Функторы и классы-декораторы | ООП Python

  Рет қаралды 58,229

selfedu

selfedu

2 жыл бұрын

Курс по Python ООП: stepik.org/a/116336
Разбираем работу магического метода _call_ на конкретных примерах. Узнаете как с его помощью можно заменять замыкания функций и создавать классы-декораторы функций.
Инфо-сайт: proproprogs.ru/python_oop
Telegram-канал: t.me/python_selfedu

Пікірлер: 72
@gggutya
@gggutya 10 ай бұрын
Грустно что в школах нет таких учителей, радостно что они есть на ютубе
@user-cb1kz3mv7j
@user-cb1kz3mv7j 3 ай бұрын
Я думаю, если бы в школах платили такую же зарплату, что получают только очень хорошие программисты, то Сергей был бы там учителем. А свой собственный курс на степике, был бы неплохой добавкой к этой зарплате. Сейчас профессию учителя просто втоптали в грязь. А ведь ее важность не меньше, чем у какого-нибудь врача. Врач жизни спасает. А чтобы стать хорошим врачом - надо выучиться. Хреновый учитель, даже будущего гения так отворожит от своего предмета, что тот до конца жизни будет считать себя бездарем в этой теме.
@user-rp7sg6eo4b
@user-rp7sg6eo4b 4 ай бұрын
Лайк, но всё же присоединюсь к тем кого начало трясти от косинусов и синусов, нам бы на яблоках понять Сергей... ))
@NAMASTE4815162342108
@NAMASTE4815162342108 2 жыл бұрын
Супер)) Спасибо большое, Сергей) ещё бы обещанный Синглтон через __call__ и __new__ и будет счастье)
@user-ku4eg2gz3n
@user-ku4eg2gz3n 2 жыл бұрын
class MetaSingleton(type): __instances = None def __call__(cls, *args, **kwargs): if cls.__instances is None: cls.__instances = super().__call__(*args, **kwargs) return cls.__instances class Database(metaclass=MetaSingleton): def __init__(self, user, psw, port): self.user = user self.psw = psw self.port = port db1 = Database('root', '123456', 80) db2= Database('root2', '456123', 40) print(id(db1), id(db2)) print(db1.__dict__) print(db2.__dict__)
@user-cb1kz3mv7j
@user-cb1kz3mv7j 3 ай бұрын
Все понял, кроме вычисления самой производной)) Пожалуй, надо будет завтра обновить знание, что же это такое.
@user-ee1lx1pe7n
@user-ee1lx1pe7n Жыл бұрын
Божественно! Огромнейшая вам благодарность!!!!!!
@KonstantinPrydnikov1
@KonstantinPrydnikov1 2 жыл бұрын
Глубина курса уровня Бог) спасибо за погружение, уже почти нет рыбы, скоро увидим черных курильщиков)
@user-bw5in2yo7s
@user-bw5in2yo7s 2 жыл бұрын
Потрясающе доходчиво
@gienek_mscislawski
@gienek_mscislawski 2 жыл бұрын
Здорово! Получается намного компактнее, чем написать параметрический декоратор с кучей вложенных функций
@user-et4if5gs8z
@user-et4if5gs8z 2 жыл бұрын
Спасибо, товарищ Балакирев! лайк
@igorratnik2357
@igorratnik2357 Жыл бұрын
Офигеть как годно! Спасибище Сергей!!!
@abdulloakramov7941
@abdulloakramov7941 10 ай бұрын
Спасибо за отличный урок 🫡
@alexhayes4253
@alexhayes4253 Жыл бұрын
Вот вам для сравнения подхода ООП и функционального. Замыкание из урока, реализованное на функциях: def strip_chars(chars): def stripit(s): res = s.strip(chars) return res return stripit s1 = strip_chars(chars = '?:!.; ') s2 = strip_chars(' ') res = s1(' Hello world! ') res2 = s2(' Hello world! ') print(res) print(res2) Декоратор на функциях: def derivate(func): def wrapper(x, dx=0.0001): res = (func(x + dx) - func(x)) / dx return res return wrapper @derivate def df_sin(x): return math.sin(x) #df_sin = derivate(df_sin) print(df_sin(math.pi/3))
@Regina_in_youtube
@Regina_in_youtube 7 ай бұрын
Сергей, спасибо за объяснение! Вы для меня учитель №1 по Питону (его изучаю). Спасибо за все видео!
@donfedor007
@donfedor007 2 жыл бұрын
Классы декораторы это круто!
@OPPACHblu_channel
@OPPACHblu_channel Жыл бұрын
Спасибо за урок
@user-yo2oi7qz3l
@user-yo2oi7qz3l Жыл бұрын
С Сергеем не только питон выучу , но и геометрию подтяну😄
@Uniter_ua
@Uniter_ua Жыл бұрын
Я в перше зробив клас декоратор було інтересно!!! Дуже дякую👍
@andredru4278
@andredru4278 4 ай бұрын
Спасибо. Ого! крутизна!
@jamjam3337
@jamjam3337 Жыл бұрын
Спасибо!
@dubinin_s
@dubinin_s 2 жыл бұрын
Вторая часть видео не вызывает вопросов, но от первой немного закипает голова. Прошу прощения если мой вопрос глупый, я всего лишь учусь. Откуда вызывается метод __call__, если он не определен в классе? Я так понимаю из базового object. Но если мы его переопределим в нашем классе, как у вас показано, то вызывая класс для создания экземпляра, отработает __call__ из класса в котором __new__ нет и соответственно экземпляр не будет создан. Так же Вы говорили, что метод __new__ отработает всегда при создании экземпляра, тогда зачем его вызывать из __call__, как показано у вас в примере? Бывают глупые вопросы, ответить на которые сложно и долго, поэтому если об этом можно более подробно прочитать, подскажите где, буду признателен.
@selfedu_rus
@selfedu_rus 2 жыл бұрын
Да, у вас хороший вопрос. Здесь есть один нюанс. Когда мы определяем метод __call__, то он вызывается только для экземпляров класса, но не для самого класса. Поэтому, когда мы создаем объекты класса, например, pt = Point(), то здесь вызывается __call__ для класса, который определен в метаклассе type (о метаклассах я еще буду рассказывать). Надеюсь, теперь будет понятнее )
@dubinin_s
@dubinin_s 2 жыл бұрын
@@selfedu_rus спасибо огромное, теперь все предельно понятно.
@junPY
@junPY 11 ай бұрын
От души!
@artemliuboshenko6639
@artemliuboshenko6639 2 жыл бұрын
Супер)) Спасибо большое, Сергей) ещё бы обещанный Синглтон через _call_ и _new_ и будет счастье), самостоятельно я в тупике _ нужна помощь !!!! Тоже очень интересует этот вопрос
@vltoropov677
@vltoropov677 2 жыл бұрын
Самое ценное в этом уроке - вспомнил что такое производная). Немного отвлекся, освежил эту, благополучно забытую, математическую тему. Еще бы уяснить разницу между производной функции и дифферениалом. По мне, сейчас, так это одно и то же. Огромное спасибо Сергею Михайловичу! Изучаю Python пока в качестве хобби. Пробегаю по быстрому оба курса - начальный и ООП. Знакомлюсь пока, где и что лежит. 90% понятно сразу, потому что очень дельно изложено. Знаю, что Python это инструмент к математике, на что явно указывают другие курсы Сергея. Вот потом от них и буду возвращаться к языку и досконально вникать в ньюансы. Еще раз спасибо!!!
@ibrahimoglu
@ibrahimoglu 2 жыл бұрын
👍
@impellergimpeller5133
@impellergimpeller5133 2 жыл бұрын
👍👍👍👍👍
@user-pg8ry1tm3t
@user-pg8ry1tm3t 5 ай бұрын
Как раз в принципе все функции в питоне - функторы по существу. Чистых функций и переменных в питоне как бы и нет🥴 все объекты, т.е. экземпляры классов
@Receive_
@Receive_ 2 жыл бұрын
Нужно дополнительное пояснение, что то совсем запутался я. В момент создания экземпляра класса строкой df_sin = Derivate(df_sin) выполняется функция df_sin, так как аргумент func содержит ссылку на функцию df_sin и присваивает значение - sin(x), приватному атрибуту self.__fn, где x это аргумент принимающий значения = (х + dx) и (x) в строке формулы метода __Call__. Строка print(df_sin(math.pi/3) - запускает магический метод __Call__, где аргумент х получает значение - math.pi/3 и выполняется формула, результат которой, посредством команды return возвращается в функцию print, которая выводит результат на экран. Я все правильно понял?
@blanky_nap
@blanky_nap 11 ай бұрын
Может underscore?
@user-xl7jy7il8m
@user-xl7jy7il8m Жыл бұрын
Декораторы - это как китайский! Но очень интересно! :)))
@alexlm2598
@alexlm2598 2 жыл бұрын
опечатка небольшая у вас, правильно не underscope, а underscore
@selfedu_rus
@selfedu_rus 2 жыл бұрын
да, заметил уже позже, спасибо! )
@Tulad
@Tulad 3 ай бұрын
У вас опечатка - "underscoRe" 😉
@selfedu_rus
@selfedu_rus 3 ай бұрын
есть такое )
@gbo4net
@gbo4net Жыл бұрын
#43. Области видимости переменных. Ключевые слова global и nonlocal | Python для начинающих kzbin.info/www/bejne/ipLGqoqmiqtkgc0 #44. Замыкания в Python | Python для начинающих kzbin.info/www/bejne/qXupaIKDg8x_i9U #45. Введение в декораторы функций | Python для начинающих kzbin.info/www/bejne/rGHUi4Omod-qi7M #46. Декораторы с параметрами. Сохранение свойств декорируемых функций | Python для начинающих kzbin.info/www/bejne/mJ3CdKF_i9WKo7M
@igorratnik2357
@igorratnik2357 Жыл бұрын
Тоже сразу вспомнились замыкания
@Developer_python_
@Developer_python_ Жыл бұрын
Вернувся ставити лайки великій людині)
@mopnrx2012
@mopnrx2012 4 ай бұрын
Подскажите пожалуйста, почему удаление символов (в 1 примере) происходит только в начале и в конце?
@Developer_python_
@Developer_python_ Жыл бұрын
Крутий урок- розумієш як писати свої кастомні декоратори-класи
@Zavintyshka
@Zavintyshka Жыл бұрын
Сергей здраствуйте! Скажите пожалуйста правильно ли я понял: сначала имя df_sin ссылается на объект функции в памяти и у этого объекта счетчик ссылок равен 1. Потом когда функция df_sin декорируется, имя df_sin ссылается на экземпляр класса Derivate. Получается счетчик ссылок уменьшается на 1 и мгновенно увеличивается на 1 за счет того, что атрибут __fn у экземпляра df_sin начинает ссылаться на эту область памяти.
@selfedu_rus
@selfedu_rus Жыл бұрын
Команда df_sin = Derivate(df_sin) создает объект класса Derivate и внутри объекта сохраняется ссылка на функцию df_sin. Далее, команда df_sin(math.pi/4) вызывает метод __call__ объекта класса Derivate и выполняется то, что записано внутри этого метода. Все, никаких счетчиков! Подробнее - телеграм-канал по Python.
@rogozin_ilya
@rogozin_ilya 2 жыл бұрын
Что быстрее работает? Есть смысл использовать классы вместо декораторов?
@selfedu_rus
@selfedu_rus 2 жыл бұрын
Думаю, разницы в скорости вы здесь не заметите ) А так, что удобнее, то и используйте.
@playt_pythonlearn
@playt_pythonlearn 2 жыл бұрын
11:00
@user-cp6ne8nr4u
@user-cp6ne8nr4u Жыл бұрын
Про удаление символов не очень понятно. Повторила в точности программу - мне пишет "Аргумент должен быть строкой".
@redvizer8337
@redvizer8337 Жыл бұрын
def __call__(self, mul, *args, **kwargs): def wrapper(x, dx=0.0001, *args, **kwargs): return (self.func(x + dx) - self.func(x)) / dx * mul return wrapper вопрос как в эту конструкцию поступает ссылка на функцию в пайчарме все сработало но если вспомнить функции декораторы, то там мы писали во внешней функции ссылку на функцию в качестве параметра здесь же я не понимаю где ссылка или она автоматически туда попадет при вызове __call__?
@Piro_
@Piro_ Жыл бұрын
В методе call есть ссылка self, функция будет искаться в экземпляре класса, в котором определена функция (funk) через self.funk( ) - self тут основное.
@teacherit5840
@teacherit5840 Жыл бұрын
Подскажите, если __call__ вызывается в момент создания экз класса, и он вызывает __new__ и __init__, то почему если делать пошагово то увидим , что сначала работает __new__ , затем __init__, и только если мы вызываем сам экземпляр то работает __call__
@teacherit5840
@teacherit5840 Жыл бұрын
#12. Магический метод __call__. Функторы и классы-декораторы #dunder - методы от англ. double underscore #Магический метод __call__ ''' В действительности, когда происходит вызов класса, то автоматически запускается магический метод __call__ и в данном случае он создает новый экземпляр этого класса: ''' """ c = Counter() def __call__ (self, *args, **kwargs): obj = self._new_(self, *args, **kwargs) self._init_(obj, *args, **kwargs) return obj """ #Функторы - это классы с определённым оператором(). Мы сможем вызвать экз класса class Counter: def __init__(self): print('вызов метода __init__') self.__counter = 0 def __new__(cls, *args, **kwargs): print('вызов метода __new__') return super().__new__(cls) def __call__(self, step = 1, *args, **kwargs): print('вызов метода __call__') self.__counter += step return self.__counter c = Counter() c2 = Counter() """Благодаря методу __call__, мы можем вызывать экземпляры класса подобно функции""" c() c(2) res = c(10) res2 = c2(-5) print(res, res2)
@selfedu_rus
@selfedu_rus Жыл бұрын
здесь метод __call__ вызывается у метакласса, а не тот, что объявлен в классе. Когда мы объявляем __call__ в классе, то он вызывается для объектов этого класса (не при создании, а при вызове их подобно функциям).
@VGCor
@VGCor Жыл бұрын
Получается декораторы на классах менее гибки, потому что на них можно реализовать лишь двойной уровень вложенности. Чаще, как по мне, применяется тройной уровень вложенности. Да и для понимания тройного уровня вложенности не нужно знание ООП, только понимание областей видимости.
@selfedu_rus
@selfedu_rus Жыл бұрын
на уровне ООП вполне можно делать и декораторы с параметрами, если вы об этом (подробно рассматривается в курсе по ООП на Stepik)
@user-sh3wb1cy5f
@user-sh3wb1cy5f 2 жыл бұрын
Привет. Делал сайт по твоим видео, решил добавить функцию "Поделиться статьёй", но я потерпел неудачу. При отправке имейла, через send_mail() после "sock.connect(sa)", вылазит эта зараза "ConnectionRefusedError: [WinError 10061] Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение".Весь интернет перерыл. Я могу тебе задонатить сколько скажешь(в пределал разумного).Буду благодарен невероятно!
@bandiwor8823
@bandiwor8823 2 жыл бұрын
Могу попробовать тебе помочь сам. Была такая ошибка у меня
@user-sh3wb1cy5f
@user-sh3wb1cy5f 2 жыл бұрын
@@bandiwor8823 буду очень благодарен. Что от меня нужно?
@user-ku4eg2gz3n
@user-ku4eg2gz3n 2 жыл бұрын
А зачем переопределять метод __call__, если мы можем просто не перезаписывать свойства? class DataBase: __instance = None def __new__(self, *args, **kwargs): if self.__instance is None: self.__instance = super().__new__(self) return self.__instance def __init__(self, user, psw, port): if not hasattr(self, 'user'): self.user = user if not hasattr(self, 'psw'): self.psw = psw if not hasattr(self, 'port'): self.port = port def __del__(self): self.__instance = None db1 = DataBase('root', '123456', 80) db2 = DataBase('root2', '456123', 40) print(id(db1), id(db2)) print(db1.__dict__) print(db2.__dict__)
@user-lk4jx9sn9t
@user-lk4jx9sn9t 6 ай бұрын
разве это не тоже самое: ";hello world! ".strip("?:!,; ")? причем тут замыкание?
@sonoffjord2773
@sonoffjord2773 Жыл бұрын
math - мэвс
@rembomenlee
@rembomenlee 8 күн бұрын
Можно бы попроще объяснять не включая сложные вычисления в код которые отвлекают от сути метода...
@stasvolo1180
@stasvolo1180 7 ай бұрын
"матч"... Хд
@nbvfnbvf
@nbvfnbvf 2 жыл бұрын
Спасибо за видео! Вот только. Match читается "мэтч", а math - "мэз"!
@ValentinKurilyuk
@ValentinKurilyuk 9 ай бұрын
Согласен. Только это не урок английского. Я готов и к неидеальной дикции и к "русскому" английскому Сергея, т.к. для объяснения теории Питона это не существенно.
@nbvfnbvf
@nbvfnbvf 9 ай бұрын
@@ValentinKurilyuk Ну, да. Поскольку видео про питон, строго запрещено потратить 10 минут и заглянуть в словарь. Видео посмотрят дети, они буду все это повторять. Оправдание - оно как ...
@torri11
@torri11 2 жыл бұрын
примеры нужно брать проще. 2+2 .А синусы косинусы тут ни чему. Потому что надо еще вспоминать что это такое.
@hjehf9094
@hjehf9094 2 жыл бұрын
Позор тебе, тут теорию гомотопий надо
@user-zy5jq3xu8y
@user-zy5jq3xu8y Жыл бұрын
не понимаю, зачем было усложнять пример синусами, пи, импортом math ??? очень отвлекает. Результат 0. и 16 цифр ...... нафиг он нужен? какая-то производная. куча слов которые сходу и не вспомнишь. функция должна быть x * 2 или х + 2!!!! вот и хватит. тут главное декораторы понять, а не вспомнить всю математику. p.s.: а на каком уроке объясняли что значит F7 и F8 ??? не понимаю, почему жмется то ф7, то ф8.
@user-ie2ey9cs2k
@user-ie2ey9cs2k 5 ай бұрын
тебе подробный гайд по блокноту тоже записать?
@PavelNebo
@PavelNebo 9 ай бұрын
Выглядит намного красивее и компактнее, чем обычный вариант с вложенными функциями! Особенно в случае с декоратором с параметрами, где 3 функции вложены друг в друга
@GetEnjoyChannel
@GetEnjoyChannel Жыл бұрын
благодаря вам прохожу стажировку в Aston
3 wheeler new bike fitting
00:19
Ruhul Shorts
Рет қаралды 50 МЛН
THEY WANTED TO TAKE ALL HIS GOODIES 🍫🥤🍟😂
00:17
OKUNJATA
Рет қаралды 4,4 МЛН
FOOLED THE GUARD🤢
00:54
INO
Рет қаралды 62 МЛН
Always be more smart #shorts
00:32
Jin and Hattie
Рет қаралды 34 МЛН
Объектно ориентированное программирование в Python за 10 минут!
12:56
Хауди Хо™ - Просто о мире IT!
Рет қаралды 666 М.
__new__ или __init__ в Python? Знаете ли вы это..
12:37
Морозов Иван собеседование python junior разработчик
1:02:31
Декораторы в Python
19:45
Программирование 2.0
Рет қаралды 13 М.
3 wheeler new bike fitting
00:19
Ruhul Shorts
Рет қаралды 50 МЛН