#24. Полиморфизм и абстрактные методы | Объектно-ориентированное программирование Python
HTML-код
- Опубликовано: 28 дек 2021
- Курс по Python ООП: stepik.org/a/116336
Что такое полиморфизм и пример его реализации в Python. Есть ли абстрактные методы в Python и как можно реализовать подобный им функционал.
Плейлист по Python ООП: • Объектно-ориентированн...
Инфо-сайт: proproprogs.ru/python_oop
Telegram-канал: t.me/python_selfedu
Сергей Михайлович, наикрутейшие и наипонятнейшие объяснения в каждом видео! Доходит даже до меня-мамы в декрете! Тысяча благодарностей Вам😁 Пусть все мечты сбываются 💫
Спасибо за видео! Улыбнулся на моменте создания треугольника со сторонами 1, 2, 3 =)
Сергей, спасибо за отличный курс по ООП! Единственное пожелание по данному разделу - добавить про библиотеку "abc", абстрактные классы и декоратор @abstractmethod. Удачи!
Уже которое видео смотрю и каждый раз говорю: "Да этот человек гений!"
Сергей, какой же ты отличный учитель! Прекрасный пример для объяснения, легкое и логичное объяснение, чистый звук и т.д. Ты -лучший! 😘😘😘
Охринеть только сейчас находять разработчиком на php, понял всю мощь и крутизну абстрактных классов, когда ты в родительском (абстрактно классе) обьявляешь метод, а уже потомки его реализуют, очень крутой полиморфизм получается!!! )
Благодаря тебе не только освоил ооп, но и интерфейсы наконец то понял что чего)! Спасибо. Полиморфизм мощь
Изучаю Python и программирование в целом больше года уже, и только после простомтра этого видео урока я до конца понял что такое 'полиморфизм' и зачем нужны 'абстрактные методы'.
Спасибо большое!!!
Изучаю Python 4 года, 2.5 из них работаю python-разработчиком, и только после просмотра этого видео я немного понял, что такое "полиморфизм" 😅
Охринеть это работает! Советую всем попробывать и прочувствовать полиморфизм) Инверсия вывода, базовый класс, вызывает внешнюю реализацию, через общий интерфейс
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
этап сериализации
общие правила форматирование
проверка валидации
хиширование информации
отправляем данные пользователю
Первым, что пришло в голову при начале обьяснения темы, что методы классов должны иметь одинаковое имя. Кстати в Пайтон появился модуль ABS
Не думал что полиморфизм что-то настолько простое, звучит куда страшнее чем есть) Это круто что так легко можно упростить и универсализировать код
Можно было обьяснить за минуту НО подход автора очень крут- уже не забудешь)))
Как всегда респектище! Очень хороший познавательный ролик. Я понимаю Вашу позицию, Вы сначала выдаёте всё по сложному, чтобы напрячь мысли, А в конце выдаёте самый простой и понятный вариант!
Ваааауу, как доступно! спасибо вам большое!!!
Учусь на втором курсе на программиста, уже раза 3-4 смотрел лекции про полиморфизм и пытался понять логику концепции. Только сейчас, благодаря тебе, дошло. Спасибо. Примеры кайф
Спасибо! Очень понятное объяснение. Как всегда.)
Спасибо, много искал объяснения абстрактных классов, только у вас понял смысл, доступно и понятно!
Как же вы подаёте эту музыку! Фантастика! Заседание продолжается, господа присяжные!
Спасибо. Действительно лучший обучающий канал по этой тематике.
С наступающим и удачи в новом году
ОООООчень доходчивое объяснение!!!!!!!
Отлично поданый материал, спасибо
Сергей. Михалыч. С наступающим 2022м!
От всёй души! От всего сердца! Огромнейший рахмат за ваш благородный труд.
Балакиреву Ура! Ура! Ура!
Всех с новыи годом.
"программа получается корявой, в ней не красоты не гибкости", - это же как надо любить свою работу?! А вообще, браво, маэстро, очень популярно и доходчиво, огромное спасибо!
Добрые день, Сергей, большое спасибо за Ваши уроки, сильно выручают, когда начинаю закапываться в теме.
Для читающих комментарии хотел предложить чуть другую реализацию, на мой взгляд более удобную, но это кому как:
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)
Спасибо! C наступающим!
Прочитал статью про абстрактные методы на proglib и вообще не понял, для чего они нужны. Вроде бы питон выдаст ошибку и когда метод просто не определен, и когда вызывается абстрактый метод. Новичку вообще не очевидно, чем одна ошибка лучше другой:) А тут все доходчиво объяснено. Спасибо!
Спасибо! Ты гений!!!
Спасибо. Прояснилось понимание полиморфизма.
Наконец то дошел до полиморфизма очень хорошее объяснение 😌👍в Джаве помню про абстракцию, но напрочь забыл что это и как это спасибо что напомнил😁😁😁
спасибо) круто!
Серёга, ты красава
еще крутой полиморфизм это Вызов метода дочернего класса из базового . это вообще отрыв башки)) спустя 2 года узнал)) Хотелось бы побольше узнать о таких крутых фишках , от тебя
Сергей говорил, что это очень нежелательно использовать
спасибо
А когда ждать продолжение подробнее по этой теме ⁉️
👍👍👍👍👍
👍
Спасибо. Очень понятно и доступно . Расскажите, пожалуйста , о модуле ABC и декораторе @abstractmethod.СПАСИБО
Чем больше учу Python после C++, тем больше понимаю, насколько всё криво реализовано в питоне с точки зрения ООП для таких базовых вещей (например, абстрактный метод) чем в других ООП языках *facepalm*
Либо же создатели языка намеренно не хотели давать возможность легко создать абстрактный метод/класс с помощью синтаксических средств языка, либо же интерпретируемый язык с динамической типизацией затрудняет это сделать. Хотя лёгкое решение это добавление декоратора @abstractmethod, который как раз генерит исключение.
Или те же protected атрибуты, которые буквально ломают важнейший принцип ООП - инкапсуляцию, давая доступ к атрибуту извне.
Но не исключаю, что это просто моё столкновение двух разных парадигм, и старая парадигма сопротивляется и поэтому возникает такое ощущение про "кривую реализацию" :)
в списке geon , "Rectangle(1,2)" - это указатель на объект класса получается и инициализация уже произошла( вызов метода __init__) в момент определения этого списка тем самым объект уже создан??
Отличная подача, все очень доходчиво.
Хочу задать вопрос по по разъяснению реализации класса родителя без реализации, вы назвали его «абстрактным классом», может это больше на «интерфейс» похоже, вроде методы в абстрактных классах могут иметь раилизацию в отличии от интерфейсов. Ещё раз благодарю за вашу работу, ваш канал очень помогает в обучении.
Спасибо! Терминология везде разная. Интерфейсы есть в Java - там для этого отдельное ключевое слово. В Python все формально называется классами и объектами классов. Поэтому говорить здесь интерфейс думаю будет очень смело )) Но это лишь вопрос теминологии не более того. Суть не меняется.
@@selfedu_rus Я думаю, что всё же, мы наследуемся, а не имплементируем, так, что это ближе к абстрактному классу, а не интерфейсу(согласен с вами) =)
Спасибо за видео. А как же модуль abc? В нём как раз всё что необходимо для абстрактных классов. Или это будет чуть позже?
Здесь все же базовый функционал. Модуль abc он лишь имитирует абстракцию, в Python ее нет (такой как в С++ или Java).
Сергей, а можно ли утверждать (на примере списков), что полиморфизм - это применение метода append к разным отдельным созданным объектам класса list ?
Формально полиморфизм, когда есть один интерфейс, работающий с разными типами данных. Метод append подходит под это понятие.
@@selfedu_rus спасибо
Сергей здравствуйте! Спасибо за прекрасные уроки. У меня вопрос возник в том моменте когда вы сделали более читабельным код и список 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)].
Тут в списке уже классы фигурируют а не экземпляры классов? Ничего если их имена два раза повторяются?
В списке экземпляры классов
Сергей, треугольника со сторонами 1, 2 и 3 не существует 😆
да, это я дал лиху ))
Хм, чёт теперь не догоняю - нафига подобная реализация вообще нужна в 90% случаев, если можно определить формулу в ините наследника, а функцию в родителе, которая и будет вызывать данную формулу? Это даст расширяемость "из коробки" так сказать...
А за объяснение - спасибо) нужно подновлять теорию время от времени)
В Python полиморфизм, действительно, вшит в сам язык. Его здесь сложно показать.
Здраствуйте, а сколько в будет уроков по ООП на питоне?
где то 35
а как вывести имя дочернего класса в котором произошла ошибка?
raise NotImplementedError("В дочерний класс: " + str(self.__class__))
Тут все неправильно, во-первых, полиморфизма в Питоне нет. То что вы написали это переопределение. Вы об этом уже говорили его называют еще (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.
спасибо
👍