Объяснение "Зачем" - это ключевой момент, как мне кажется. Без этого все эти методы просто набор команд, которые выветрятся из памяти без применения. А понимая зачем, больше шансов, что они вспомнятся в нужный момент)))
Ролик всего лишь чуть более пятнадцати минут, а чтобы утоптать его в голову, понадобился без малого целый день. И то степень усвоения материала - иллюзия понимания. Автору очередное большое спасибо.
сидишь и пробуешь написать ручками, а потом что-то ради интереса поменять, чаще всего, когда непонятно "а как это повлияет на результат и сойдется ли с моим ожидаемый". У меня на каждую тему благодаря такому методу 30-40 мин уходит
@@xximdeПолитика везде, от неё не куда не спрятаться. Как говорил великий Немчинский, если ты не интересуешься политикой то ты не зрелый человек, вот такие пироги🤷🏻♂️
Огромное спасибо! Всегда любил учиться по системе "Если тема не понятна, меняй спикеров/учителей" и на вашем примере сработало, вы первый кто сказал что-то , что не говорили остальные и все встало на свое место :) 4:25 сижу такой и бамс, все понял , спасибо!🤩
Сергей, жму Вам руку! Отличный материал! Смотрю как уменьшается количество просмотров и лайков от урока к уроку, все таки курс ориентирован не на новичков. Но для тех кто знаком с ООП ваш материал просто клад!
Спасибо за вашу работу! Уверен, буду использовать этот раздел (ооп) в своих программах (пока такой уровень)). Отдельное спасибо за очень подробное объяснение основ (в первых видео этого плейлиста), это сильно упрощает последующее обучение. Удачи вам в продвижении!
Урок #7 = Пройден Было интересно узнать о существовании этих методов, и что их можно переопределять. Вряд ли конечно, что они будут на постоянной основе использоваться на практике, но все же, сам факт того, что их тоже можно контролировать, радует :) Спасибо за урок. Эти 3 часа, прошли достаточно быстро. Думаю, сегодня уже закончу, и вернусь завтра.
Сергей, доброго времени суток. Вас беспокоит Бог. За ваш бескорыстный труд я приготовил вам место в раю. Увидимся не скоро: я вам нормально так жизню продлил. Спасибо вам и всего светлого!
__ЧЕКПОИНТ__ Смотрю видео уроки уже 7 день подряд пытаясь изучить ооп и у меня отлично получается! Спасибо огромное Сергею,за предоставленные знания,а я прошу пожелать мне удачи в понимании следующих тем)
Может кому - то так станет понятно если он не понял. Немного забегу вперед, поскольку я сначала проходил менее подробный курс и там было про наследование, то я лично смог это понять относительно легко именно поэтому, как мне кажется. Когда мы наследуем любой класс в другой класс, мы это делаем по средствам скобок после названия класса и прописываем внутри название класса от которого наследуем, в случае с классом object мы неявно наследуем его по умолчанию, как тут и сказано собственно. Мы наследуем все атрибуты класса, кроме понятно защищенных от этого. И в данном случае хоть мы и не видим все эти атрибуты в теле класса, мы всеровно можем к ним обращаться, а когда мы прописываем метод внутри дочернего класса с названием которое уже существует в материнском классе, то мы выполняем так называемое переопределение атрибута, то есть теперь у нас есть атрибут с таким же названием как в материнском классе, но выполняет он теперь при вывозе тот функционал который мы прописали. А таким синтаксисом: название_материнского_класса.название_материнского_атрибута(необходимые аргументы) мы как раз возвращаем весь тот функционал что содержится внутри материнского метода с таким же названием. Как я понимаю переопределение метода класса происходит по такому же принципу как создание атрибута для экземпляра класса, то есть когда мы создаем атрибут с таким же названием внутри класса, то python сразу находит нужный нам атрибут внутри дочернего класса и поэтому не начинает искать в материнском классе на который ссылается этот самый дочерний
@selfedu_rus - its genius 🎉 Вы настолько тонко подметили про "z" attribute, что я тут же пришел в сообщения Вам написать, насколько Вы правы и заметил, что я не один такой 😉 Спасибо, очень интересные, компактные и емкие лекции. 👍🏻
Очень интересные и познавательные уроки, спасибо вам! Только мне кажется, что перед подачей данного материала было бы хорошо людям обьяснить про наследование от object, потому что без понимание этого, тяжело понять материал в этом уроке, что и почему делается. Спасибо
Благодарю за урок. Хорошее разъяснение присваивания с self на 2:50. По примеру метода __setattr__: если удалить строку с "object ...", то в результате выполнения кода всё равно метод вызывается 4 раза. Для чего тогда строка "object ..."?
Строка с "object.__setattr__" обеспечивает непосредственно работоспособность метода. А то, что наблюдается вызов 4 раза, это всего лишь отрабатывает print() внутри этого метода, то есть метод был вызван, но без строки с "object" он никакой работы не выполнил. И чтобы убедиться в этом достаточно вывести все атрибуты после инициализации через pt1.__dict__, например. И попробовать это сделать со строкой "object.__setattr__" и без неё.
Здравствуйте, в примере использования метода __getattribute__ можно ли просто сделать этот атрибут приватным как на предыдущим уроке где рассказывалось о режимах доступа? Или это будем совсем другое
С одной стороны, хорошо, что наконец появились видео по этой теме, но с другой стороны как-то обидно, что буквально месяц назад, для одной задачки с кодворс я сам около недели искал информацию по метапрлграммированию и магическим методам, сам разбирался в найденном, при том половина была на английском, а здесь про магические методы рассказывается буквально за пару видео и при этом понятно и информативно Появляется ощущение, что старания были напрасны(
Возможно вам стоит оставлять номер или ссылки для донатов под видео. Настолько понравились видео, что я бы вам задонатил небольшую сумму. И наверно еще такие люди найдутся :)
Не могу понять, почему для получения значения атрибута под return необходимо обращаться через object да еще и атрибуты такие же в скобках ставить, как и в самом методе?
Благодарю за столь понятное пояснение! Подскажите, в чем разница между Super и object? Когда мы используем метод __new__, мы обращаемся к Super(), а здесь же для __delattr__ (и всех остальных в этом видео) - используем object. Мы ведь и для __new__ тоже можем использовать object?
Спасибо! Разница в том, что super() позволяет обращаться непосредственно к базовому классу (а иерархия наследования может быть самой разной), а через object мы обращаемся к самой вершине иерархии.
Можно вопрос тем кто шарит? когда мы переопределяем метод __getattribute__ мы указали object как базовый класс и передали self и item ( object.__getattribute__(self, item) ). Но насколько я понял мы можем также указать вместо object super(). Но когда используешь super() то нужно передавать только item. ( super().__getattribute__(item)). Почему такая разница если мы в и том и в другом случае ссылаемся на родительский класс object ???
@@selfedu_rusСпасибо за ответ! Правильно ли я понимаю, что использования super() как ссылку на базовый класс для переопределение методов не будет ошибкой? или же правильнее указывать сам базовый класс?
почему при создании экземпляра класса через __new__ мы вызываем super(), а при использовании этих магических методов просто обращаемся к нему как object? Edit: super() возвращает ссылку на object, а когда пишем object, то напрямую обращаемся? Тогда есть ли разница в этих способах доступа к базовому классу?
@@beribanyu Как понял я: Если мы используем object, то при return нам нужно указать первым параметром self, а при использовании super это делается автоматически. То есть ,по сути, одно и тоже
Выглядит так, что на посленем слайде, где написано __setattr__(self, key, value)__ - автоматически вызывается при изменении свойства кеу класса; два нижних подчеркивания после (self, key, value) лишние. Верно ли это замечание? Или они там нужны?
8:32 А почему работа с атрибутами private типа не работает примерно так? ( Для примера представим, что у нас в классе есть два приватных атрибута __x, __y) Так ведь не выйдет получить доступ, обращаясь к полям таким образом ._ def __getattribute__(self, item): if item in ("_Point__x", "_Point__y"): raise ValueError(f"There no access to item: {item}") else: return object.__getattribute__(self, item)
Если вы хотите совсем жестко запретить доступ, то как вариант, но на практике достаточно просто пометить атрибуты как private или protected, чтобы программист знал, что к ним не следует обращаться. Ну а если он нарушит это правило, то работоспособность программы на его совести. Профессионалы так не делают.
@@hesha-n9b Если у вас имеется иерархия наследования, то родительский уже будет не object, т.е. функция-объект super() возвратит другой класс и из-за этого возможны ошибки. Поэтому здесь лучше обращаться через object.
Кстати, ещё вопрос на уточнение. Я правильно понимаю, все классы, которые не наследуются от созданных нами, наследуются от object, у которого метакласс это type?
да, в версии Python3 все классы неявно наследуются от object, если не прописаны какие-либо другие базовые классы и также у всех классов по умолчанию идет метакласс type.
а можно ли в данном примере с __getattribute__ обращаться к родительскому классу через super().__getattribute__() и если да, то в чём будет отличие от обращения через object.__getattribute__()
При множественном наследовании super() дает непосредственно текущий базовый класс, а не самый базовый object. Во всем остальном без разницы. Метод __getattribute__() можно и так и так вызывать.
Интрересно, что с методом __getattribute__ такой же фокус, как с __setattr__ не прокатывает и: def __getattribute__(self, item): print("here is the value:") return self.__dict__[item] вызывается рекурсивно. Почему так?
Думаю потому,что __dict__ тоже является атрибутом self. И self.__dict__ [item] по сути является вызовом (получением) атрибута этого экземпляра, что вызывает рекурсию. Но лучше подождать объяснения от автора))
А при использовании __setattr__ хоть мы и изменяем содержимое атрибута __dict__,но не делаем это напрямую, например self.__dict__ = что то, а меняем один из его элементов (некоторый атрибут self'а), и это не считается за изменение атрибута, поэтому рекурсии нет. Опять же, автор лучше знает, я высказал что думаю)
Только что отвечал на это в ТГ-канале. Подписывайтесь на него. Приоритет вызова дескриптора выше, чем у обычной переменной, поэтому конструкция self.name=name вызывает дескриптор по рекурсии
|__setattr__| вызывается всякий раз при присвоении. Если в нем присвоить значение, то он опять вызовется, опять присвоится, опять вызовется и вот рекурсия
Спасибо за ролик! Подскажите, пожалуйста. В примере с помощью переопределения ___getattribute___ вы сделали так, чтобы не было возможности обращаться к атрибуту "x". Правильно понимаю, что на практике правильнее будет сделать переменную "x" приватной, а не использовать переопределение __getattribute__? И ещё у меня в PyCharm ___getattribute___ вызывается даже если просто написать Point(), то есть, необязательно присваивать переменную для вызова ___getattribute___, это, наверное, потому что у меня более новая версия Python?
Поправьте меня если я не прав, но во второй части напутано, пом меньшей мере в терминологии... 5.25 - здесь в определениях говорится о "свойствах класса", когда в реальности рассказывается об instance variables, а не о class variables, как можно подумать, и как подумает любой, ведь в первой части рассказывалось именно о class variables.
зачем существует и object и super()? При чём __new__ работает через оба вызова, а __getattribute___ только через вызов object? похоже что super ссылается просто на родителя, а object к object - самому верхнему классу
Почему удаление не происходило при записи del pt1.x , а только потом, когда дописали метод def __delattr__ (self, item): object.__delattr__(self,item) ? Ведь по сути этот метод нужен для создания доп действий при удалении какого-то атрибута. Либо же object.__delattr__(self,item) как раз ставит точку в этой операции удаления(del pt1.x)?
@@selfedu_rus на 14:14 print(pt1.__dict__) вернул {'x':1, 'y':2}. Пользователь скорее всего спрашивает почему из коллекции __dict__ x удалился только после дописания object.__delattr__(self,item) в метод _delattr_. Посмотрев ваше видео попробую ответить. Магический метод __delattr__ вызывается при удалении атрибутов экземпляра класса, т.е. происходит только вызов метода. Доп действия вы уже сами придумываете при переопределении магического метода. Так как переопределив мы написали print("__delattr__ :"+item), то при удалении атрибута произойдет только вывод строки. Конкретно логика удаления атрибута происходит в базовом классе object в __delattr__ , именно поэтому необходимо дописать вызов object.__delattr__(self, item) в нашем переопределенном методе __delattr__ класса Point.
разработчики питона такие: "значит в __del__ не нужно всяких усложнений делать. он вызывается именно при удалении, за само удаление не отвечает, а __delattr__ - это другое..."
А зачем Вам что-либо возвращать из этого метода? Вы уже определили новый атрибут через super().__setattr__(...). А если нужно вернуть значение атрибута, то уже непосредственно вызывается метод get
спасибо за урок!) не совсем понимаю как это работает) похоже на то что эти магические методы при создании класса автоматически добавляются без их определения и работают в каком то "режиме по умолчанию"...а когда уже мы их объявляем - мы их работу немного корректируем по своему усмотрению... либо я не понял как мы после определения метода вызываем тот же метод : def __getattribute__(self,item): return object.__getattribute__(self,item):
object - это самый верхний (базовый) класс, а super() выдает следующий базовый, от которого мы наследовались. Если наследований явных не было, то super() и object ведут на один и тот же класс.
метод object.__setattr__() как раз и делает установку атрибутов, поэтому лучше к нему сразу и идти, если прописать super().__setattr__(), то из-за иерархии наследования поиск может идти до object.__setattr__() дольше
@@selfedu_rus это понятно, но я немного о другом. 11:53 почему лучше всего использовать object.__setattr__(self, key, value) вместо self.__dict__[key] = value? У меня конструкция такая: for attr in attrs: self.__dict__[attr].__dict__["new_attr"] = "Default value" И как в этой конструкции применить __setattr__ не понимаю.
@@VGCor я бы использовал .__setattr__() вместо прямого обращения к __dict__, хотя иногда приходится работать напрямую со словарем (чтобы избежать рекурсии вызовов __setattr__())
В вакууме, понятное дело, все это лютейшая абстракция. Но если потыкаться самому, сделать хотя бы простенький проект с применением этих штук - очень быстро доходит, как по мне. Ну и еще имеет смысл держать в голове, что ООП раскрывает себя на реально огромных проектах, где находят применение методы из этого видоса, например. Если интерес есть, можешь посмотреть какие-нибудь опенсорс проекты, чтобы увидеть реализацию на практике И честно, на этом канале обычно самая понятная подача материала, как минимум для меня, из всего, что я смотрел/читал, в том числе и по ООП Вообще, если прям докапываться, хотелось бы побольше отсылок на примеры из реальных задач, где все это применяется и реализацию, но это такое
Понятно практически все, что Сергей объясняет, но лично я, веду конспект всего материала, иначе информация не удерживается в голове, по крайней мере, у меня. И обязательно закрепляю практикой большую часть материала. Конечно, если просто смотреть, как киношку, то толку 0.
Объяснение "Зачем" - это ключевой момент, как мне кажется. Без этого все эти методы просто набор команд, которые выветрятся из памяти без применения. А понимая зачем, больше шансов, что они вспомнятся в нужный момент)))
Особая благодарность за разъяснения "зачем".
СПАСИБО Вам за Ваш труд! Ваши лекции лучшие из тех, что встречаются на просторах Ютуба.
10:05 - мы все не хотели, но он появился... Спасибо огромное даже за такое высказывание скрытое, уже теплее на душе стало
ага, только видео то было залито 26 нояб. 2021 г.
Наверное воспользовались:
object.__settattr__(pt1, 'z', 5)
Которое смогло обойти ограничение в переопределенном магическом методе.
Ролик всего лишь чуть более пятнадцати минут, а чтобы утоптать его в голову, понадобился без малого целый день. И то степень усвоения материала - иллюзия понимания. Автору очередное большое спасибо.
Как же точно вы описали мое состояние. А я все понять не мог, что именно не так.
сидишь и пробуешь написать ручками, а потом что-то ради интереса поменять, чаще всего, когда непонятно "а как это повлияет на результат и сойдется ли с моим ожидаемый". У меня на каждую тему благодаря такому методу 30-40 мин уходит
Запрет z спустя 5 месяцев приобретает свой смысл, лайк за видео, как всегда.
Отличный способ запретить Z использовав setattr. Пример как всегда актуальный
Осталось удалить из английского алфавита
Везде надо приплести политику, клоун
@@xximdeПолитика везде, от неё не куда не спрятаться.
Как говорил великий Немчинский, если ты не интересуешься политикой то ты не зрелый человек, вот такие пироги🤷🏻♂️
Спасибо за лёгкую и приятную подачу сухого материала! Ваше речевые обороты искренне радуют - "будем полагать, что мы теперь хорошо понимаем" - :)
Огромное спасибо! Всегда любил учиться по системе "Если тема не понятна, меняй спикеров/учителей" и на вашем примере сработало, вы первый кто сказал что-то , что не говорили остальные и все встало на свое место :) 4:25 сижу такой и бамс, все понял , спасибо!🤩
Сергей, жму Вам руку! Отличный материал! Смотрю как уменьшается количество просмотров и лайков от урока к уроку, все таки курс ориентирован не на новичков. Но для тех кто знаком с ООП ваш материал просто клад!
Спасибо за вашу работу! Уверен, буду использовать этот раздел (ооп) в своих программах (пока такой уровень)). Отдельное спасибо за очень подробное объяснение основ (в первых видео этого плейлиста), это сильно упрощает последующее обучение. Удачи вам в продвижении!
Огромное спасибо за такую интересную и подробную подачу материала! Вы очень талантливый преподаватель и делаете большое дело, Спасибо!
Сергей, спасибо за труд! Очень качественный материал и доходчивое разъяснение
Урок #7 = Пройден
Было интересно узнать о существовании этих методов, и что их можно переопределять. Вряд ли конечно, что они будут на постоянной основе использоваться на практике, но все же, сам факт того, что их тоже можно контролировать, радует :)
Спасибо за урок. Эти 3 часа, прошли достаточно быстро. Думаю, сегодня уже закончу, и вернусь завтра.
Молодец программист, начал хоть что то понимать в ООП
Сергей, доброго времени суток. Вас беспокоит Бог. За ваш бескорыстный труд я приготовил вам место в раю. Увидимся не скоро: я вам нормально так жизню продлил. Спасибо вам и всего светлого!
Большое спасибо Вам за такие уроки!
__ЧЕКПОИНТ__
Смотрю видео уроки уже 7 день подряд пытаясь изучить ооп и у меня отлично получается! Спасибо огромное Сергею,за предоставленные знания,а я прошу пожелать мне удачи в понимании следующих тем)
могу поинтересоваться как продвижение за почти пол года?
@@kalivann досмотрел курс по ооп,написал парочку проектов и забил, собираюсь изучить c# и попробовать сделать чит для игры
Спасибо, посмотрела!!!
Отличный урок!!! Буду смотреть все ваши уроки... Спасибо огромное !!!
Спасибо за классные уроки! И мне сердечко!)
Спасибо! Очень четкое объяснение магических методов.
Спасибо. Отличные примеры!
Интересное занятие! Можно добавлять гибкость в свой код, этими методами!
10:06 Мы бы не хотели что бы создавался атрибут с именем Зет("z") :)
ахахаха
Обидно
хахах, я тож заметил.. потом глянул дату выхода видео - 26 нояб. 2021 г. Он что-то знал ?)))
@@zetmixbeatz почему обидно? Єто знак нацистов и ужасних людей.
@@spraysferry9841 на мой ник взгляни
Блин, ютуб, для таких видео давно должна быть функция "поставить тыщу лайков" !!!!
Может кому - то так станет понятно если он не понял. Немного забегу вперед, поскольку я сначала проходил менее подробный курс и там было про наследование, то я лично смог это понять относительно легко именно поэтому, как мне кажется. Когда мы наследуем любой класс в другой класс, мы это делаем по средствам скобок после названия класса и прописываем внутри название класса от которого наследуем, в случае с классом object мы неявно наследуем его по умолчанию, как тут и сказано собственно. Мы наследуем все атрибуты класса, кроме понятно защищенных от этого. И в данном случае хоть мы и не видим все эти атрибуты в теле класса, мы всеровно можем к ним обращаться, а когда мы прописываем метод внутри дочернего класса с названием которое уже существует в материнском классе, то мы выполняем так называемое переопределение атрибута, то есть теперь у нас есть атрибут с таким же названием как в материнском классе, но выполняет он теперь при вывозе тот функционал который мы прописали. А таким синтаксисом: название_материнского_класса.название_материнского_атрибута(необходимые аргументы) мы как раз возвращаем весь тот функционал что содержится внутри материнского метода с таким же названием. Как я понимаю переопределение метода класса происходит по такому же принципу как создание атрибута для экземпляра класса, то есть когда мы создаем атрибут с таким же названием внутри класса, то python сразу находит нужный нам атрибут внутри дочернего класса и поэтому не начинает искать в материнском классе на который ссылается этот самый дочерний
Сергей, благодарю!! 👍🔥💯
Этот урок слушал 5 раз.
С первого раза туго пошло, второй раз пересмотрел через пару часов и всё понял. Если что-то не понятно, советую такой подход.
Спасибо за урок! Не знал и использовал костыли :)
Вау! Спасибо большое!
Это многое упрощает😅
необычной понятности примеры
Супергениальный урок!!!
Лучший! Спасибо
Дуже круто мені понравилось.
Спасибо Сергею за бан атрибута, с названием Z
Невероятно крут
@selfedu_rus - its genius 🎉
Вы настолько тонко подметили про "z" attribute, что я тут же пришел в сообщения Вам написать, насколько Вы правы и заметил, что я не один такой 😉
Спасибо, очень интересные, компактные и емкие лекции. 👍🏻
думаю все поняли о чем шла речь.
☮
Очень интересные и познавательные уроки, спасибо вам!
Только мне кажется, что перед подачей данного материала было бы хорошо людям обьяснить про наследование от object, потому что без понимание этого, тяжело понять материал в этом уроке, что и почему делается.
Спасибо
Спасибо! Про object будет дальше в теме наследование
@@selfedu_rus на данном этапе можно было использовать super() как в прошлом уроке? или так не сработало бы?
Благодарю за урок.
Хорошее разъяснение присваивания с self на 2:50.
По примеру метода __setattr__: если удалить строку с "object ...", то в результате выполнения кода всё равно метод вызывается 4 раза. Для чего тогда строка "object ..."?
Строка с "object.__setattr__" обеспечивает непосредственно работоспособность метода. А то, что наблюдается вызов 4 раза, это всего лишь отрабатывает print() внутри этого метода, то есть метод был вызван, но без строки с "object" он никакой работы не выполнил. И чтобы убедиться в этом достаточно вывести все атрибуты после инициализации через pt1.__dict__, например. И попробовать это сделать со строкой "object.__setattr__" и без неё.
Здравствуйте, в примере использования метода __getattribute__ можно ли просто сделать этот атрибут приватным как на предыдущим уроке где рассказывалось о режимах доступа? Или это будем совсем другое
Мы бы не хотели, чтобы появлялся атрибут "z". Внезапно)
и случайно ))
Тоже вот хотел такое же написать, а оно раз - и есть уже))
С одной стороны, хорошо, что наконец появились видео по этой теме, но с другой стороны как-то обидно, что буквально месяц назад, для одной задачки с кодворс я сам около недели искал информацию по метапрлграммированию и магическим методам, сам разбирался в найденном, при том половина была на английском, а здесь про магические методы рассказывается буквально за пару видео и при этом понятно и информативно
Появляется ощущение, что старания были напрасны(
Спасибо за урок
спасибо!👏👍
Возможно вам стоит оставлять номер или ссылки для донатов под видео. Настолько понравились видео, что я бы вам задонатил небольшую сумму. И наверно еще такие люди найдутся :)
спасибо, просто сейчас многие такие сервисы отсеялись, поэтому кроме yoomoney кошелька нечего указывать...
Не могу понять, почему для получения значения атрибута под return необходимо обращаться через object да еще и атрибуты такие же в скобках ставить, как и в самом методе?
спасибо огромное
Спасибо
Благодарю за столь понятное пояснение! Подскажите, в чем разница между Super и object? Когда мы используем метод __new__, мы обращаемся к Super(), а здесь же для __delattr__ (и всех остальных в этом видео) - используем object. Мы ведь и для __new__ тоже можем использовать object?
Спасибо! Разница в том, что super() позволяет обращаться непосредственно к базовому классу (а иерархия наследования может быть самой разной), а через object мы обращаемся к самой вершине иерархии.
@@selfedu_rus
Огромное спасибо!
Можно вопрос тем кто шарит? когда мы переопределяем метод __getattribute__ мы указали object как базовый класс и передали self и item ( object.__getattribute__(self, item) ). Но насколько я понял мы можем также указать вместо object super(). Но когда используешь super() то нужно передавать только item. ( super().__getattribute__(item)). Почему такая разница если мы в и том и в другом случае ссылаемся на родительский класс object ???
очень просто, object - это сам базовый класс, а super() - это объект базового класса, поэтому первый параметр self передается автоматически.
@@selfedu_rusСпасибо за ответ! Правильно ли я понимаю, что использования super() как ссылку на базовый класс для переопределение методов не будет ошибкой? или же правильнее указывать сам базовый класс?
@@ДмитрийСафронов-р2ълучше super()
@@selfedu_rus Спасибо за объяснения!
почему при создании экземпляра класса через __new__ мы вызываем super(), а при использовании этих магических методов просто обращаемся к нему как object?
Edit: super() возвращает ссылку на object, а когда пишем object, то напрямую обращаемся? Тогда есть ли разница в этих способах доступа к базовому классу?
Поддерживаю вопрос, тоже интересно
@@beribanyu Как понял я: Если мы используем object, то при return нам нужно указать первым параметром self, а при использовании super это делается автоматически. То есть ,по сути, одно и тоже
Выглядит так, что на посленем слайде, где написано __setattr__(self, key, value)__ - автоматически вызывается при изменении
свойства кеу класса;
два нижних подчеркивания после (self, key, value) лишние. Верно ли это замечание? Или они там нужны?
Я так понимаю мы "якобы" меняем поведение магического метода но просто вызывая это у object можно сказать что мы засовываем промежуточные команды.
Спасибо за уроки 🖖👍
спасибо
Правильно ли я понимаю, что в видео в местах переопределения магических методов происходит один из принципов ооп - полиморфизм?
Первый, как всегда лайк.
А какая разница между этими магическими методами и дискрипторами?
Здравствуйте! Я так понимаю return object.__getattribute__(self, item) и return super().__getattribute__(item) это аналогичные записи?
в целом, да
8:32
А почему работа с атрибутами private типа не работает примерно так? ( Для примера представим, что у нас в классе
есть два приватных атрибута __x, __y)
Так ведь не выйдет получить доступ, обращаясь к полям
таким образом ._
def __getattribute__(self, item):
if item in ("_Point__x", "_Point__y"):
raise ValueError(f"There no access to item: {item}")
else:
return object.__getattribute__(self, item)
Если вы хотите совсем жестко запретить доступ, то как вариант, но на практике достаточно просто пометить атрибуты как private или protected, чтобы программист знал, что к ним не следует обращаться. Ну а если он нарушит это правило, то работоспособность программы на его совести. Профессионалы так не делают.
@@selfedu_rus Понял, спасибо.
На 6:41 есть ли разница между object.__getattribute__(self, item) и super().__getattribute__(item) ?
Нет, разницы не будет
@@selfedu_rus почему тогда при использовании super().__delattr__(item) возникла ошибка, а при object.__delattr__(self, item) нет?
@@hesha-n9b Если у вас имеется иерархия наследования, то родительский уже будет не object, т.е. функция-объект super() возвратит другой класс и из-за этого возможны ошибки. Поэтому здесь лучше обращаться через object.
понемногу становлюсь магом
привет
Кстати, ещё вопрос на уточнение. Я правильно понимаю, все классы, которые не наследуются от созданных нами, наследуются от object, у которого метакласс это type?
да, в версии Python3 все классы неявно наследуются от object, если не прописаны какие-либо другие базовые классы и также у всех классов по умолчанию идет метакласс type.
Теперь понятно где можно использовать @classmethod 😅
а можно ли в данном примере с __getattribute__ обращаться к родительскому классу через super().__getattribute__() и если да, то в чём будет отличие от обращения через object.__getattribute__()
При множественном наследовании super() дает непосредственно текущий базовый класс, а не самый базовый object. Во всем остальном без разницы. Метод __getattribute__() можно и так и так вызывать.
10:05 актуальненько))
Интрересно, что с методом __getattribute__ такой же фокус, как с __setattr__ не прокатывает и:
def __getattribute__(self, item):
print("here is the value:")
return self.__dict__[item]
вызывается рекурсивно. Почему так?
Думаю потому,что __dict__ тоже является атрибутом self. И self.__dict__ [item] по сути является вызовом (получением) атрибута этого экземпляра, что вызывает рекурсию. Но лучше подождать объяснения от автора))
А при использовании __setattr__ хоть мы и изменяем содержимое атрибута __dict__,но не делаем это напрямую, например self.__dict__ = что то, а меняем один из его элементов (некоторый атрибут self'а), и это не считается за изменение атрибута, поэтому рекурсии нет. Опять же, автор лучше знает, я высказал что думаю)
возможно туповатый вопрос, но зачем создавать атрибут, чтобы потом запретить обращаться к нему? 8:20
да, это конечно вопрос вопросов ))) в примере особо им не по пользуешься, просто демонстрация принципа работы не более того
👍👍👍👍👍
Такой вопрос, это нужно больше для понимания или же применяется на практике?
урок как всегда супер, все понял, спасибо вам))
Спасибо! На практике это все используется, лучше знать, лишнее я стараюсь не давать.
Станут ли задания по ООП на степике когда-нибудь бесплатными ?)
нет
как часто эти атрибуты используются в реальной работе?
Достаточно часто, что бы знать как пользоваться
Можете, пожалуйста, подсказать, почему в __setattr__, если присваивать значение атрибуту определенному, открывается рекурсия?
Только что отвечал на это в ТГ-канале. Подписывайтесь на него.
Приоритет вызова дескриптора выше, чем у обычной переменной, поэтому конструкция self.name=name вызывает дескриптор по рекурсии
|__setattr__| вызывается всякий раз при присвоении. Если в нем присвоить значение, то он опять вызовется, опять присвоится, опять вызовется и вот рекурсия
@@Majohne спасибо Вам большое! Теперь я поняла😊
@@selfedu_rus спасибо большое Вам!😊
Спасибо за ролик! Подскажите, пожалуйста. В примере с помощью переопределения ___getattribute___ вы сделали так, чтобы не было возможности обращаться к атрибуту "x". Правильно понимаю, что на практике правильнее будет сделать переменную "x" приватной, а не использовать переопределение __getattribute__?
И ещё у меня в PyCharm ___getattribute___ вызывается даже если просто написать Point(), то есть, необязательно присваивать переменную для вызова ___getattribute___, это, наверное, потому что у меня более новая версия Python?
Почему при вызове магических методов __new__() мы обращались к классу super(), а при вызове этих магических методов обращаемся к классу object
object - это самый базовый класс, а super() возвращает первый базовый класс (на данном уровне object и super() работают одинаково)
@@selfedu_rus спасибо
Мы бы не хотели, чтобы появлялся атрибут с именем 'Z'. Очень актуально
😁
вуду-программист)
Если бы в реальной жизни можно было просто взять и написать эксепшен)))
С хрена ли? Этому атрибуту везде дорога.
@@vilag_programmer Нет
Поправьте меня если я не прав, но во второй части напутано, пом меньшей мере в терминологии... 5.25 - здесь в определениях говорится о "свойствах класса", когда в реальности рассказывается об instance variables, а не о class variables, как можно подумать, и как подумает любой, ведь в первой части рассказывалось именно о class variables.
Магические методы __setattr__, __getattribute__, __getattr__ и __delattr__ служат для обработки локальных атрибутов экземпляров классов
зачем существует и object и super()? При чём __new__ работает через оба вызова, а __getattribute___ только через вызов object?
похоже что super ссылается просто на родителя, а object к object - самому верхнему классу
Это простые вопросы в ТГ-канал по Python. Сообщество ответит.
сам ответил на свой вопрос )
👍
А вместо object можно написать super?
да
Почему удаление не происходило при записи del pt1.x ,
а только потом, когда дописали метод
def __delattr__ (self, item):
object.__delattr__(self,item)
?
Ведь по сути этот метод нужен для создания доп действий при удалении какого-то атрибута.
Либо же object.__delattr__(self,item) как раз ставит точку в этой операции удаления(del pt1.x)?
проверил, все удаляет, что то не так сделали, видимо
@@selfedu_rus на 14:14 print(pt1.__dict__) вернул {'x':1, 'y':2}. Пользователь скорее всего спрашивает почему из коллекции __dict__ x удалился только после дописания object.__delattr__(self,item) в метод _delattr_.
Посмотрев ваше видео попробую ответить. Магический метод __delattr__ вызывается при удалении атрибутов экземпляра класса, т.е. происходит только вызов метода. Доп действия вы уже сами придумываете при переопределении магического метода. Так как переопределив мы написали print("__delattr__ :"+item), то при удалении атрибута произойдет только вывод строки. Конкретно логика удаления атрибута происходит в базовом классе object в __delattr__ , именно поэтому необходимо дописать вызов object.__delattr__(self, item) в нашем переопределенном методе __delattr__ класса Point.
Так получается MIN_CORD в случае когда мы не юзаем classmethod для присвоения ему значения - становиться атрибутом экземпляра класса?
да, т.к. мы используем ссылку на класс
разработчики питона такие: "значит в __del__ не нужно всяких усложнений делать. он вызывается именно при удалении, за само удаление не отвечает, а __delattr__ - это другое..."
А почему вызывается именно object?
Все классы в питоне неявно наследуются от object, поэтому и вызывается именно он, т.к. в нем прописаны все эти маг. методы.
Почему в __setattr__ не используется return? Опечатка или его особенность?
А зачем Вам что-либо возвращать из этого метода? Вы уже определили новый атрибут через super().__setattr__(...). А если нужно вернуть значение атрибута, то уже непосредственно вызывается метод get
спасибо за урок!)
не совсем понимаю как это работает) похоже на то что эти магические методы при создании класса автоматически добавляются без их определения и работают в каком то "режиме по умолчанию"...а когда уже мы их объявляем - мы их работу немного корректируем по своему усмотрению...
либо я не понял как мы после определения метода вызываем тот же метод :
def __getattribute__(self,item):
return object.__getattribute__(self,item):
да, все верно, каждый класс в Python3 наследуется (неявно) от object
@@selfedu_rus а , ну то есть они все в object уже прописаны)) спасибо!)
А почему раньше мы обращались к родительскому классу через super а тут через object? Можно вместо object писать super?
object - это самый верхний (базовый) класс, а super() выдает следующий базовый, от которого мы наследовались. Если наследований явных не было, то super() и object ведут на один и тот же класс.
А почему если мы хотим изменить атрибут класса Point, нам просто не написать Point.min_coord = 100 ? вместо целого classmethod ?
чтобы через экземпляр класса менять атрибут класса
Всё же до конца не понятно, почему вместо обращения к словарю с атрибутами лучше использовать object.__setattr__()?
метод object.__setattr__() как раз и делает установку атрибутов, поэтому лучше к нему сразу и идти, если прописать super().__setattr__(), то из-за иерархии наследования поиск может идти до object.__setattr__() дольше
@@selfedu_rus это понятно, но я немного о другом.
11:53 почему лучше всего использовать object.__setattr__(self, key, value) вместо self.__dict__[key] = value?
У меня конструкция такая:
for attr in attrs:
self.__dict__[attr].__dict__["new_attr"] = "Default value"
И как в этой конструкции применить __setattr__ не понимаю.
@@VGCor я бы использовал .__setattr__() вместо прямого обращения к __dict__, хотя иногда приходится работать напрямую со словарем (чтобы избежать рекурсии вызовов __setattr__())
а почему вызов через object. а не через super()?
сам и отвечу) погуглил - и так и так можно)
@@x-user-agent Но только если ваш класс не наследуется от другого
Ребзя как долго вы учите Pyhton и что хотите на нем писать???
4 месяца, работать з данными и парсингом
Я запутался, понятия "атрибут класса" и "свойство класса" - это синонимы
в общем, да, но чаще СВОЙСТВА я отношу к переменным, а АТРИБУТЫ - ко всем элементам класса (методам, переменным и т.п.)
@@selfedu_rus Хорошо, спасибо
запрет на букву z:)
В Украине уже как полтора года запрещены атрибуты Z😁
Есть тут люди которые проходят и главное понимают все что он снимает ? Как вы это будете применять на практике и ТД
В вакууме, понятное дело, все это лютейшая абстракция. Но если потыкаться самому, сделать хотя бы простенький проект с применением этих штук - очень быстро доходит, как по мне. Ну и еще имеет смысл держать в голове, что ООП раскрывает себя на реально огромных проектах, где находят применение методы из этого видоса, например. Если интерес есть, можешь посмотреть какие-нибудь опенсорс проекты, чтобы увидеть реализацию на практике
И честно, на этом канале обычно самая понятная подача материала, как минимум для меня, из всего, что я смотрел/читал, в том числе и по ООП
Вообще, если прям докапываться, хотелось бы побольше отсылок на примеры из реальных задач, где все это применяется и реализацию, но это такое
Посмотрите фреймворк Django (на этом канале) и увидите, что он без ООП просто немыслим )
Понятно практически все, что Сергей объясняет, но лично я, веду конспект всего материала, иначе информация не удерживается в голове, по крайней мере, у меня. И обязательно закрепляю практикой большую часть материала. Конечно, если просто смотреть, как киношку, то толку 0.
@@KonstantinYurievich Полностью с вами согласен, так же конспектирую в отдельном файле