Ответ
В контексте 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() успешно работает с нашим объектом