#24. Полиморфизм и абстрактные методы | Объектно-ориентированное программирование Python
ฝัง
- เผยแพร่เมื่อ 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м!
От всёй души! От всего сердца! Огромнейший рахмат за ваш благородный труд.
Балакиреву Ура! Ура! Ура!
Всех с новыи годом.
Спасибо, много искал объяснения абстрактных классов, только у вас понял смысл, доступно и понятно!
Прочитал статью про абстрактные методы на 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)
Спасибо. Прояснилось понимание полиморфизма.
Ваааауу, как доступно! спасибо вам большое!!!
Спасибо. Действительно лучший обучающий канал по этой тематике.
С наступающим и удачи в новом году
спасибо
Спасибо! Очень понятное объяснение. Как всегда.)
А когда ждать продолжение подробнее по этой теме ⁉️
ОООООчень доходчивое объяснение!!!!!!!
еще крутой полиморфизм это Вызов метода дочернего класса из базового . это вообще отрыв башки)) спустя 2 года узнал)) Хотелось бы побольше узнать о таких крутых фишках , от тебя
Сергей говорил, что это очень нежелательно использовать
Отлично поданый материал, спасибо
Спасибо! C наступающим!
Наконец то дошел до полиморфизма очень хорошее объяснение 😌👍в Джаве помню про абстракцию, но напрочь забыл что это и как это спасибо что напомнил😁😁😁
Спасибо! Ты гений!!!
Серёга, ты красава
спасибо) круто!
👍👍👍👍👍
Чем больше учу Python после C++, тем больше понимаю, насколько всё криво реализовано в питоне с точки зрения ООП для таких базовых вещей (например, абстрактный метод) чем в других ООП языках *facepalm*
Либо же создатели языка намеренно не хотели давать возможность легко создать абстрактный метод/класс с помощью синтаксических средств языка, либо же интерпретируемый язык с динамической типизацией затрудняет это сделать. Хотя лёгкое решение это добавление декоратора @abstractmethod, который как раз генерит исключение.
Или те же protected атрибуты, которые буквально ломают важнейший принцип ООП - инкапсуляцию, давая доступ к атрибуту извне.
Но не исключаю, что это просто моё столкновение двух разных парадигм, и старая парадигма сопротивляется и поэтому возникает такое ощущение про "кривую реализацию" :)
Спасибо. Очень понятно и доступно . Расскажите, пожалуйста , о модуле ABC и декораторе @abstractmethod.СПАСИБО
в списке geon , "Rectangle(1,2)" - это указатель на объект класса получается и инициализация уже произошла( вызов метода __init__) в момент определения этого списка тем самым объект уже создан??
Спасибо за видео. А как же модуль abc? В нём как раз всё что необходимо для абстрактных классов. Или это будет чуть позже?
Здесь все же базовый функционал. Модуль abc он лишь имитирует абстракцию, в Python ее нет (такой как в С++ или Java).
Сергей, а можно ли утверждать (на примере списков), что полиморфизм - это применение метода append к разным отдельным созданным объектам класса list ?
Формально полиморфизм, когда есть один интерфейс, работающий с разными типами данных. Метод append подходит под это понятие.
@@selfedu_rus спасибо
👍
Отличная подача, все очень доходчиво.
Хочу задать вопрос по по разъяснению реализации класса родителя без реализации, вы назвали его «абстрактным классом», может это больше на «интерфейс» похоже, вроде методы в абстрактных классах могут иметь раилизацию в отличии от интерфейсов. Ещё раз благодарю за вашу работу, ваш канал очень помогает в обучении.
Спасибо! Терминология везде разная. Интерфейсы есть в Java - там для этого отдельное ключевое слово. В Python все формально называется классами и объектами классов. Поэтому говорить здесь интерфейс думаю будет очень смело )) Но это лишь вопрос теминологии не более того. Суть не меняется.
@@selfedu_rus Я думаю, что всё же, мы наследуемся, а не имплементируем, так, что это ближе к абстрактному классу, а не интерфейсу(согласен с вами) =)
Сергей, треугольника со сторонами 1, 2 и 3 не существует 😆
да, это я дал лиху ))
Сергей здравствуйте! Спасибо за прекрасные уроки. У меня вопрос возник в том моменте когда вы сделали более читабельным код и список 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)].
Тут в списке уже классы фигурируют а не экземпляры классов? Ничего если их имена два раза повторяются?
В списке экземпляры классов
а как вывести имя дочернего класса в котором произошла ошибка?
raise NotImplementedError("В дочерний класс: " + str(self.__class__))
Хм, чёт теперь не догоняю - нафига подобная реализация вообще нужна в 90% случаев, если можно определить формулу в ините наследника, а функцию в родителе, которая и будет вызывать данную формулу? Это даст расширяемость "из коробки" так сказать...
А за объяснение - спасибо) нужно подновлять теорию время от времени)
В Python полиморфизм, действительно, вшит в сам язык. Его здесь сложно показать.
Здраствуйте, а сколько в будет уроков по ООП на питоне?
где то 35
Тут все неправильно, во-первых, полиморфизма в Питоне нет. То что вы написали это переопределение. Вы об этом уже говорили его называют еще (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.
спасибо
👍