Какие виды полиморфизма применяются к функциям в Python

Ответ

В контексте Python под полиморфизмом функций понимают способность одной функции или оператора работать с объектами разных типов. Основные формы, которые можно встретить:

1. Ad-hoc полиморфизм (Перегрузка)

Это возможность определять несколько версий функции для разных типов аргументов. В Python это реализуется не через одинаковые имена функций (как в C++ или Java), а с помощью декоратора @singledispatch из модуля functools.

Пример: Создадим функцию format_value, которая по-разному форматирует целые числа и строки.

from functools import singledispatch

@singledispatch
def format_value(value):
    """Базовая реализация по умолчанию."""
    return str(value)

@format_value.register(int)
def _(value):
    """Реализация для целых чисел (int)."""
    return f"Integer: {value}"

@format_value.register(str)
def _(value):
    """Реализация для строк (str)."""
    return f'String: "{value}"'

print(format_value(123))         # Вывод: Integer: 123
print(format_value("hello"))     # Вывод: String: "hello"
print(format_value([1, 2, 3]))  # Вывод: [1, 2, 3] (используется базовая реализация)

2. Параметрический полиморфизм (через утиную типизацию)

Это способность функции выполняться одинаково для любого типа данных, который поддерживает необходимые ей операции. В Python это достигается за счет утиной типизации (duck typing): "если что-то крякает как утка и плавает как утка, то это утка". Тип объекта не важен, важны лишь его методы и атрибуты.

Пример: Встроенная функция len() работает с любым объектом, у которого есть метод __len__().

# len() работает со строкой, списком и словарем
print(len("Python"))      # 6
print(len([1, 2, 3, 4]))  # 4
print(len({"a": 1, "b": 2})) # 2

# Создадим свой класс с методом __len__
class Order:
    def __init__(self, items):
        self.items = items

    def __len__(self):
        return len(self.items)

my_order = Order(["apple", "banana", "orange"])
print(len(my_order))      # 3, len() успешно работает с нашим объектом