Ответ
В Python выделяют следующие основные типы полиморфизма:
-
Ad-hoc полиморфизм (перегрузка операторов): Позволяет одному и тому же оператору или функции выполнять разные действия в зависимости от типов операндов. Это делает код более интуитивным и читаемым, так как один символ может иметь разное, но логичное поведение.
print(1 + 2) # Сложение чисел print('a' + 'b') # Конкатенация строк print([1] + [2]) # Объединение списков
-
Параметрический полиморфизм (дженерики): Позволяет функциям или классам работать с данными разных типов без изменения их логики. В Python это часто достигается за счет динамической типизации и утиной типизации, а также с помощью модуля
typing
для статической проверки типов.def get_first_element(sequence): """Возвращает первый элемент любой последовательности.""" return sequence[0] print(get_first_element([1, 2, 3])) # 1 (для списка) print(get_first_element('abc')) # 'a' (для строки)
-
Полиморфизм подтипов (наследование и переопределение методов): Позволяет объектам разных классов, унаследованных от общего базового класса, реагировать на один и тот же вызов метода по-разному. Это основа объектно-ориентированного дизайна, способствующая расширяемости и гибкости кода.
class Animal: def speak(self): """Базовый метод, который должен быть переопределен в подклассах.""" raise NotImplementedError("Метод speak должен быть реализован в подклассе") class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" def make_animal_speak(animal: Animal): """Функция, работающая с любым объектом типа Animal.""" print(animal.speak()) make_animal_speak(Dog()) # Выведет "Woof!" make_animal_speak(Cat()) # Выведет "Meow!"
Python активно использует утиную типизацию (duck typing), где тип объекта определяется его поведением (наличием определенных методов), а не явным наследованием. Это делает полиморфизм в Python очень гибким, позволяя функциям работать с любыми объектами, которые "выглядят и ведут себя" как ожидаемый тип, без строгих ограничений по иерархии классов.