Какие типы полиморфизма существуют в Python?

Ответ

В Python выделяют следующие основные типы полиморфизма:

  1. Ad-hoc полиморфизм (перегрузка операторов): Позволяет одному и тому же оператору или функции выполнять разные действия в зависимости от типов операндов. Это делает код более интуитивным и читаемым, так как один символ может иметь разное, но логичное поведение.

    print(1 + 2)      # Сложение чисел
    print('a' + 'b')  # Конкатенация строк
    print([1] + [2])  # Объединение списков
  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' (для строки)
  3. Полиморфизм подтипов (наследование и переопределение методов): Позволяет объектам разных классов, унаследованных от общего базового класса, реагировать на один и тот же вызов метода по-разному. Это основа объектно-ориентированного дизайна, способствующая расширяемости и гибкости кода.

    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 очень гибким, позволяя функциям работать с любыми объектами, которые "выглядят и ведут себя" как ожидаемый тип, без строгих ограничений по иерархии классов.