Сергей, спасибо за отличный курс по ООП! Единственное пожелание по данному разделу - добавить про библиотеку "abc", абстрактные классы и декоратор @abstractmethod. Удачи!
Охринеть это работает! Советую всем попробывать и прочувствовать полиморфизм) Инверсия вывода, базовый класс, вызывает внешнюю реализацию, через общий интерфейс class AbstractBaseParent: def __init__(self): self.parent() def parent(self): """вызвать реализацию из дочернего класса""" self.print_test() def print_test(self): """абстрактный метод""" pass class Child(AbstractBaseParent): def __init__(self): """вызвать конструктор родителя""" super().__init__() def print_test(self): print('реализация метода') Child() а можно проще питон автоматически настроен искать полиморфизм) class AbstractBaseParent: def __init__(self): self.print_test() class Child(AbstractBaseParent): def __init__(self): """вызвать конструктор родителя""" super().__init__() def print_test(self): print('реализация метода') Child() или же так class AbstractBaseParent: def __init__(self): self.get_data() self.format() self.validation() self.protect() self.send() def validation(self): print("проверка валидации") def protect(self): print("хиширование информации") def format(self): print("общие правила форматирование") class Db(AbstractBaseParent): def __init__(self): """вызвать конструктор родителя""" super().__init__() def get_data(self): print('получаем данные из базы') def send(self): print("данные сохранены в другой базе") class Api(AbstractBaseParent): def __init__(self): """вызвать конструктор родителя""" super().__init__() def get_data(self): print('получаем данные из json') self.json_serialize() def json_serialize(self): print("этап сериализации") def send(self): print("отправляем данные пользователю") Db() print(" ---- ") Api() получаем данные из базы общие правила форматирование проверка валидации хиширование информации данные сохранены в другой базе ---- получаем данные из json этап сериализации общие правила форматирование проверка валидации хиширование информации отправляем данные пользователю
Охринеть только сейчас находять разработчиком на php, понял всю мощь и крутизну абстрактных классов, когда ты в родительском (абстрактно классе) обьявляешь метод, а уже потомки его реализуют, очень крутой полиморфизм получается!!! )
Изучаю Python и программирование в целом больше года уже, и только после простомтра этого видео урока я до конца понял что такое 'полиморфизм' и зачем нужны 'абстрактные методы'. Спасибо большое!!!
"программа получается корявой, в ней не красоты не гибкости", - это же как надо любить свою работу?! А вообще, браво, маэстро, очень популярно и доходчиво, огромное спасибо!
Сергей Михайлович, наикрутейшие и наипонятнейшие объяснения в каждом видео! Доходит даже до меня-мамы в декрете! Тысяча благодарностей Вам😁 Пусть все мечты сбываются 💫
Учусь на втором курсе на программиста, уже раза 3-4 смотрел лекции про полиморфизм и пытался понять логику концепции. Только сейчас, благодаря тебе, дошло. Спасибо. Примеры кайф
Прочитал статью про абстрактные методы на proglib и вообще не понял, для чего они нужны. Вроде бы питон выдаст ошибку и когда метод просто не определен, и когда вызывается абстрактый метод. Новичку вообще не очевидно, чем одна ошибка лучше другой:) А тут все доходчиво объяснено. Спасибо!
Как всегда респектище! Очень хороший познавательный ролик. Я понимаю Вашу позицию, Вы сначала выдаёте всё по сложному, чтобы напрячь мысли, А в конце выдаёте самый простой и понятный вариант!
Добрые день, Сергей, большое спасибо за Ваши уроки, сильно выручают, когда начинаю закапываться в теме. Для читающих комментарии хотел предложить чуть другую реализацию, на мой взгляд более удобную, но это кому как: from abc import ABC, abstractmethod class Animal(ABC): @abstractmethod def say(self): pass В чем тут соль, в данном примере мы создаем абстрактный класс Animal, вы спросите: "с какого перепуга он абстрактный то ?". А все потому что мы наследуемся от класса АВС, а абстрактным метод say() делает декоратор @abstractmethod Каковы плюсы данного подхода: 1) Не нужно возбуждать исключение NotImplementedError в абстрактном методе, можно просто поставить pass(заглушку) 2) Интерпретатор сам напомнит вам, что вы не переопределили метод в дочернем классе 3) Также, при попытке создать экземпляр абстрактного класса Animal, будет возбуждено исключение (TypeError: Can't instantiate abstract class Animal with abstract methods move, sound)
Сергей. Михалыч. С наступающим 2022м! От всёй души! От всего сердца! Огромнейший рахмат за ваш благородный труд. Балакиреву Ура! Ура! Ура! Всех с новыи годом.
Урок #24 = Пройден Емае...я просто в шоке. Сколько бы я мог сохранить времени, знав о полиморфизме. Я в своих пет проектах, как только не корявил язык, чтобы он выполнял то что мне нужно. Перерывал весь инет, в поиске решения. А вот оно, решение. ООП мощная штука!
еще крутой полиморфизм это Вызов метода дочернего класса из базового . это вообще отрыв башки)) спустя 2 года узнал)) Хотелось бы побольше узнать о таких крутых фишках , от тебя
в списке geon , "Rectangle(1,2)" - это указатель на объект класса получается и инициализация уже произошла( вызов метода __init__) в момент определения этого списка тем самым объект уже создан??
Отличная подача, все очень доходчиво. Хочу задать вопрос по по разъяснению реализации класса родителя без реализации, вы назвали его «абстрактным классом», может это больше на «интерфейс» похоже, вроде методы в абстрактных классах могут иметь раилизацию в отличии от интерфейсов. Ещё раз благодарю за вашу работу, ваш канал очень помогает в обучении.
Спасибо! Терминология везде разная. Интерфейсы есть в Java - там для этого отдельное ключевое слово. В Python все формально называется классами и объектами классов. Поэтому говорить здесь интерфейс думаю будет очень смело )) Но это лишь вопрос теминологии не более того. Суть не меняется.
Чем больше учу Python после C++, тем больше понимаю, насколько всё криво реализовано в питоне с точки зрения ООП для таких базовых вещей (например, абстрактный метод) чем в других ООП языках *facepalm* Либо же создатели языка намеренно не хотели давать возможность легко создать абстрактный метод/класс с помощью синтаксических средств языка, либо же интерпретируемый язык с динамической типизацией затрудняет это сделать. Хотя лёгкое решение это добавление декоратора @abstractmethod, который как раз генерит исключение. Или те же protected атрибуты, которые буквально ломают важнейший принцип ООП - инкапсуляцию, давая доступ к атрибуту извне. Но не исключаю, что это просто моё столкновение двух разных парадигм, и старая парадигма сопротивляется и поэтому возникает такое ощущение про "кривую реализацию" :)
Сергей здравствуйте! Спасибо за прекрасные уроки. У меня вопрос возник в том моменте когда вы сделали более читабельным код и список geom = [r1,r2,s1,s2,tr1,tr2] переделали в такой вот вид : geom = [Rectangle(7,8),Rectangle(1,2), Square(3),Square(9), Triangle(4,5,8),Triangle(6,6,9)]. Тут в списке уже классы фигурируют а не экземпляры классов? Ничего если их имена два раза повторяются?
Хм, чёт теперь не догоняю - нафига подобная реализация вообще нужна в 90% случаев, если можно определить формулу в ините наследника, а функцию в родителе, которая и будет вызывать данную формулу? Это даст расширяемость "из коробки" так сказать... А за объяснение - спасибо) нужно подновлять теорию время от времени)
Тут все неправильно, во-первых, полиморфизма в Питоне нет. То что вы написали это переопределение. Вы об этом уже говорили его называют еще (re-implementing a method или Method Overriding). Задача полиморфизма не просто вызвать метод с таким же именем, но и так же послать разные параметры. С и Java такое поддерживает, а вот Питон и Го нет. Плюс то что вы написали это не абстрактные методы, assertion на то что метод должен определится или нет, такое обычно используют для Сингелтонов конструктора. А вот если абстракт то для этого есть @abstractmethod дескриптор
Абстракция реализована в Python на нулевом уровне конечно. Нет ни абстрактных классов, методов, ни интерфейсов. Все на уровне check проверки. Неужели никак нельзя пометить метод обязательным для имплементации в дочерних классах кроме как выбрасывать исключение?
Более реальный пример когда абстрактный метод, вызывает один конкретный класс, а именно. Интересно можно ли это сделать в питоне 🤔. absract get_data() : self.get_data() (и вызываетя реализация у дочернего класса.
Разве если абстрактный метод может что то вызывать он остаётся абстрактным? Можно через super(class, instance) вызвать любой класс для данного instance.
Снимаю шляпу, определенно одно из лучших объяснений в русскоязычном ютубе
Сергей, спасибо за отличный курс по ООП! Единственное пожелание по данному разделу - добавить про библиотеку "abc", абстрактные классы и декоратор @abstractmethod. Удачи!
Сергей, какой же ты отличный учитель! Прекрасный пример для объяснения, легкое и логичное объяснение, чистый звук и т.д. Ты -лучший! 😘😘😘
Спасибо, очень понятно, вы лучший! ООП очень Добрый
Уже которое видео смотрю и каждый раз говорю: "Да этот человек гений!"
Охринеть это работает! Советую всем попробывать и прочувствовать полиморфизм) Инверсия вывода, базовый класс, вызывает внешнюю реализацию, через общий интерфейс
class AbstractBaseParent:
def __init__(self):
self.parent()
def parent(self):
"""вызвать реализацию из дочернего класса"""
self.print_test()
def print_test(self):
"""абстрактный метод"""
pass
class Child(AbstractBaseParent):
def __init__(self):
"""вызвать конструктор родителя"""
super().__init__()
def print_test(self):
print('реализация метода')
Child()
а можно проще питон автоматически настроен искать полиморфизм)
class AbstractBaseParent:
def __init__(self):
self.print_test()
class Child(AbstractBaseParent):
def __init__(self):
"""вызвать конструктор родителя"""
super().__init__()
def print_test(self):
print('реализация метода')
Child()
или же так
class AbstractBaseParent:
def __init__(self):
self.get_data()
self.format()
self.validation()
self.protect()
self.send()
def validation(self):
print("проверка валидации")
def protect(self):
print("хиширование информации")
def format(self):
print("общие правила форматирование")
class Db(AbstractBaseParent):
def __init__(self):
"""вызвать конструктор родителя"""
super().__init__()
def get_data(self):
print('получаем данные из базы')
def send(self):
print("данные сохранены в другой базе")
class Api(AbstractBaseParent):
def __init__(self):
"""вызвать конструктор родителя"""
super().__init__()
def get_data(self):
print('получаем данные из json')
self.json_serialize()
def json_serialize(self):
print("этап сериализации")
def send(self):
print("отправляем данные пользователю")
Db()
print(" ---- ")
Api()
получаем данные из базы
общие правила форматирование
проверка валидации
хиширование информации
данные сохранены в другой базе
----
получаем данные из json
этап сериализации
общие правила форматирование
проверка валидации
хиширование информации
отправляем данные пользователю
Охринеть только сейчас находять разработчиком на php, понял всю мощь и крутизну абстрактных классов, когда ты в родительском (абстрактно классе) обьявляешь метод, а уже потомки его реализуют, очень крутой полиморфизм получается!!! )
Спасибо вам сэр Сергей Балакирев, мне сейчас 13 лет , изучаю питон уже 8 месяцев и только сейчас понял что такое полиморфизм
Изучаю Python и программирование в целом больше года уже, и только после простомтра этого видео урока я до конца понял что такое 'полиморфизм' и зачем нужны 'абстрактные методы'.
Спасибо большое!!!
Изучаю Python 4 года, 2.5 из них работаю python-разработчиком, и только после просмотра этого видео я немного понял, что такое "полиморфизм" 😅
"программа получается корявой, в ней не красоты не гибкости", - это же как надо любить свою работу?! А вообще, браво, маэстро, очень популярно и доходчиво, огромное спасибо!
Чувак спасибо тебе за твой труд ! Детально и понятно
Благодаря тебе не только освоил ооп, но и интерфейсы наконец то понял что чего)! Спасибо. Полиморфизм мощь
Сергей Михайлович, наикрутейшие и наипонятнейшие объяснения в каждом видео! Доходит даже до меня-мамы в декрете! Тысяча благодарностей Вам😁 Пусть все мечты сбываются 💫
Учусь на втором курсе на программиста, уже раза 3-4 смотрел лекции про полиморфизм и пытался понять логику концепции. Только сейчас, благодаря тебе, дошло. Спасибо. Примеры кайф
Не думал что полиморфизм что-то настолько простое, звучит куда страшнее чем есть) Это круто что так легко можно упростить и универсализировать код
Прочитал статью про абстрактные методы на proglib и вообще не понял, для чего они нужны. Вроде бы питон выдаст ошибку и когда метод просто не определен, и когда вызывается абстрактый метод. Новичку вообще не очевидно, чем одна ошибка лучше другой:) А тут все доходчиво объяснено. Спасибо!
Как всегда респектище! Очень хороший познавательный ролик. Я понимаю Вашу позицию, Вы сначала выдаёте всё по сложному, чтобы напрячь мысли, А в конце выдаёте самый простой и понятный вариант!
Добрые день, Сергей, большое спасибо за Ваши уроки, сильно выручают, когда начинаю закапываться в теме.
Для читающих комментарии хотел предложить чуть другую реализацию, на мой взгляд более удобную, но это кому как:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def say(self):
pass
В чем тут соль, в данном примере мы создаем абстрактный класс Animal, вы спросите: "с какого перепуга он абстрактный то ?". А все потому что мы наследуемся от класса АВС, а абстрактным метод say() делает декоратор @abstractmethod
Каковы плюсы данного подхода:
1) Не нужно возбуждать исключение NotImplementedError в абстрактном методе, можно просто поставить pass(заглушку)
2) Интерпретатор сам напомнит вам, что вы не переопределили метод в дочернем классе
3) Также, при попытке создать экземпляр абстрактного класса Animal, будет возбуждено исключение (TypeError: Can't instantiate abstract class Animal with abstract methods move, sound)
Сергей. Михалыч. С наступающим 2022м!
От всёй души! От всего сердца! Огромнейший рахмат за ваш благородный труд.
Балакиреву Ура! Ура! Ура!
Всех с новыи годом.
Можно было обьяснить за минуту НО подход автора очень крут- уже не забудешь)))
Спасибо. Прояснилось понимание полиморфизма.
и всё? и так просто? спасибо большое за такое объяснение!!!!)
Урок #24 = Пройден
Емае...я просто в шоке. Сколько бы я мог сохранить времени, знав о полиморфизме. Я в своих пет проектах, как только не корявил язык, чтобы он выполнял то что мне нужно. Перерывал весь инет, в поиске решения. А вот оно, решение. ООП мощная штука!
Как же вы подаёте эту музыку! Фантастика! Заседание продолжается, господа присяжные!
Спасибо, много искал объяснения абстрактных классов, только у вас понял смысл, доступно и понятно!
Ваааауу, как доступно! спасибо вам большое!!!
Первым, что пришло в голову при начале обьяснения темы, что методы классов должны иметь одинаковое имя. Кстати в Пайтон появился модуль ABS
Спасибо! Очень понятное объяснение. Как всегда.)
ОООООчень доходчивое объяснение!!!!!!!
Спасибо! Ты гений!!!
спасибо
еще крутой полиморфизм это Вызов метода дочернего класса из базового . это вообще отрыв башки)) спустя 2 года узнал)) Хотелось бы побольше узнать о таких крутых фишках , от тебя
Сергей говорил, что это очень нежелательно использовать
Наконец то дошел до полиморфизма очень хорошее объяснение 😌👍в Джаве помню про абстракцию, но напрочь забыл что это и как это спасибо что напомнил😁😁😁
Отлично поданый материал, спасибо
Серёга, ты красава
Спасибо! C наступающим!
А когда ждать продолжение подробнее по этой теме ⁉️
спасибо) круто!
👍👍👍👍👍
Программист: "a = a + 1".
Математик: "?!"
Программист: "Треугольник со сторонами 1, 2, 3"
Математик: "Как скажешь..."
чет не хватает информации про модуль abc непосредственно для реализации абстрактных классов. а так в целом все доступно, спасибо
Спасибо за видео. А как же модуль abc? В нём как раз всё что необходимо для абстрактных классов. Или это будет чуть позже?
Здесь все же базовый функционал. Модуль abc он лишь имитирует абстракцию, в Python ее нет (такой как в С++ или Java).
в списке geon , "Rectangle(1,2)" - это указатель на объект класса получается и инициализация уже произошла( вызов метода __init__) в момент определения этого списка тем самым объект уже создан??
Спасибо. Очень понятно и доступно . Расскажите, пожалуйста , о модуле ABC и декораторе @abstractmethod.СПАСИБО
Сергей, а можно ли утверждать (на примере списков), что полиморфизм - это применение метода append к разным отдельным созданным объектам класса list ?
Формально полиморфизм, когда есть один интерфейс, работающий с разными типами данных. Метод append подходит под это понятие.
@@selfedu_rus спасибо
Отличная подача, все очень доходчиво.
Хочу задать вопрос по по разъяснению реализации класса родителя без реализации, вы назвали его «абстрактным классом», может это больше на «интерфейс» похоже, вроде методы в абстрактных классах могут иметь раилизацию в отличии от интерфейсов. Ещё раз благодарю за вашу работу, ваш канал очень помогает в обучении.
Спасибо! Терминология везде разная. Интерфейсы есть в Java - там для этого отдельное ключевое слово. В Python все формально называется классами и объектами классов. Поэтому говорить здесь интерфейс думаю будет очень смело )) Но это лишь вопрос теминологии не более того. Суть не меняется.
@@selfedu_rus Я думаю, что всё же, мы наследуемся, а не имплементируем, так, что это ближе к абстрактному классу, а не интерфейсу(согласен с вами) =)
Чем больше учу Python после C++, тем больше понимаю, насколько всё криво реализовано в питоне с точки зрения ООП для таких базовых вещей (например, абстрактный метод) чем в других ООП языках *facepalm*
Либо же создатели языка намеренно не хотели давать возможность легко создать абстрактный метод/класс с помощью синтаксических средств языка, либо же интерпретируемый язык с динамической типизацией затрудняет это сделать. Хотя лёгкое решение это добавление декоратора @abstractmethod, который как раз генерит исключение.
Или те же protected атрибуты, которые буквально ломают важнейший принцип ООП - инкапсуляцию, давая доступ к атрибуту извне.
Но не исключаю, что это просто моё столкновение двух разных парадигм, и старая парадигма сопротивляется и поэтому возникает такое ощущение про "кривую реализацию" :)
👍
а как вывести имя дочернего класса в котором произошла ошибка?
raise NotImplementedError("В дочерний класс: " + str(self.__class__))
Сергей здравствуйте! Спасибо за прекрасные уроки. У меня вопрос возник в том моменте когда вы сделали более читабельным код и список geom = [r1,r2,s1,s2,tr1,tr2] переделали в такой вот вид : geom = [Rectangle(7,8),Rectangle(1,2),
Square(3),Square(9),
Triangle(4,5,8),Triangle(6,6,9)].
Тут в списке уже классы фигурируют а не экземпляры классов? Ничего если их имена два раза повторяются?
В списке экземпляры классов
Хм, чёт теперь не догоняю - нафига подобная реализация вообще нужна в 90% случаев, если можно определить формулу в ините наследника, а функцию в родителе, которая и будет вызывать данную формулу? Это даст расширяемость "из коробки" так сказать...
А за объяснение - спасибо) нужно подновлять теорию время от времени)
В Python полиморфизм, действительно, вшит в сам язык. Его здесь сложно показать.
Здраствуйте, а сколько в будет уроков по ООП на питоне?
где то 35
Сергей, треугольника со сторонами 1, 2 и 3 не существует 😆
да, это я дал лиху ))
Насколько я знаю, в Python методы по умолчанию являются виртуальными, то бишь доступными для переопределения.
В Python это не имеет значения, т.к. у нас ссылки (переменные) связаны с конкретным объектом класса и приведение типов здесь отсутствует
Тут все неправильно, во-первых, полиморфизма в Питоне нет. То что вы написали это переопределение. Вы об этом уже говорили его называют еще (re-implementing a method или Method Overriding). Задача полиморфизма не просто вызвать метод с таким же именем, но и так же послать разные параметры. С и Java такое поддерживает, а вот Питон и Го нет.
Плюс то что вы написали это не абстрактные методы, assertion на то что метод должен определится или нет, такое обычно используют для Сингелтонов конструктора. А вот если абстракт то для этого есть @abstractmethod дескриптор
en.wikipedia.org/wiki/Polymorphism_(computer_science)
Абстракция реализована в Python на нулевом уровне конечно. Нет ни абстрактных классов, методов, ни интерфейсов. Все на уровне check проверки. Неужели никак нельзя пометить метод обязательным для имплементации в дочерних классах кроме как выбрасывать исключение?
можно еще через модуль abc импортировать метакласс ABC и декоратор abstractmethod: docs.python.org/3/library/abc.html
Более реальный пример когда абстрактный метод, вызывает один конкретный класс, а именно. Интересно можно ли это сделать в питоне 🤔. absract get_data() :
self.get_data() (и вызываетя реализация у дочернего класса.
Разве если абстрактный метод может что то вызывать он остаётся абстрактным? Можно через super(class, instance) вызвать любой класс для данного instance.
спасибо
👍