Множественная перегрузка функций в Python: рецепт для игровых пуль
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
В Python возможно имитировать перегрузку функций, и тем самым добиться того, что одна функция будет исполнять различные действия в зависимости от числа и типа принимаемых ей аргументов. Это осуществляется через использование такого синтаксиса как *args
и **kwargs
, а также с помощью инструкций if
и функции isinstance()
. Пример ниже иллюстрирует функцию, поведение которой отличается в зависимости от типа и количества принимаемых ей аргументов:
def func(*args):
if len(args) == 1 and isinstance(args[0], str):
return "Строка: " + args[0]
elif len(args) == 2 and all(isinstance(arg, int) for arg in args):
return "Сумма: " + str(sum(args))
print(func("тест")) # Вывод: Строка: тест
print(func(1, 2)) # Вывод: Сумма: 3
Здесь len(args)
считает количество аргументов, а isinstance()
проверяет их типы, тем самым адаптируя функцию к различным обстоятельствам.
Объединение функций с использованием singledispatch
Начиная с версии Python 3.4 стал доступен декоратор functools.singledispatch
, позволяющий менять поведение функции в зависимости от типа первого аргумента. Сначала определяется функция с декоратором @singledispatch
как обработчик по умолчанию, а затем с применением метода .register()
добавляются варианты функции для различных типов аргументов:
from functools import singledispatch
@singledispatch
def func(arg):
raise NotImplementedError("Тип не поддерживается")
@func.register(str)
def _(arg):
return "Строка: " + arg
@func.register(list)
def _(arg):
return "Список: " + str(len(arg))
Функция func
будет вызываться с разным поведением в зависимости от типа первого аргумента, передаваемого ей.
Знакомство с multipledispatch
Для работы с функциями, имеющими несколько сигнатур, подходит библиотека multipledispatch
, расширяющая возможности перегрузки функций. Однако стоит учесть, что она не обеспечивает потокобезопасность в многопоточных средах.
from multipledispatch import dispatch
@dispatch(str)
def func(arg):
return "Строка: " + arg
@dispatch(int, int)
def func(x, y):
return "Сумма: " + str(x + y)
@dispatch(list)
def func(arg):
return "Список: " + str(len(arg))
Визуализация
Чтобы наглядно представить суть перегрузки функций, давайте представим маскарадный бал. На этом балу каждый гость представляет функцию с одним и тем же именем, но "маски", которые они носят, отражают различные типы аргументов:
Гости у входа 🧙🤖🧟♂️: "Все мы — это func!"
Организатор бала, Python, определяет гостей по их "маскам" и предоставляет им специальные "браслеты". Здесь они известны как перегруженные версии:
@overload
def func(🧙: Волшебник): ...
@overload
def func(🤖: Робот): ...
@overload
def func(🧟♂️: Зомби): ...
Когда вызывается func
, Python определяет тип аргумента и активирует соответствующую реализацию функции:
func(🧙) -> "Привет, Волшебник!"
func(🤖) -> "Привет, Робот!"
func(🧟♂️) -> "Боже, Зомби!"
Примечание: Несмотря на то, что Python не поддерживает перегрузку функций на уровне языка, можно имитировать подобный функционал при помощи декоратора @overload
из модуля typing
.
Осмотрим мир мультиметодов
Существует и другой подход к перегрузке – мультиметоды. Это методы, которые не связаны ни с одним классом или объектом. Они работают как самостоятельные единицы, отказываясь от традиционной классификации с наследованием и широким использованием именованных аргументов.
Полезные материалы
- Перегрузка функций с помощью
singledispatch
– документация Python. Подробнее о перегрузке функций с помощьюsingledispatch
вы можете прочитать в официальной документации Python. - PEP 3124 – Перегрузка, общая функциональность, интерфейсы и адаптация. Дополнительную информацию по перегрузке можно извлечь из этого технического документа.
- Перегрузка функций в Python – Stack Overflow. Изучите обсуждения и советы в сообществе разработчиков на Stack Overflow для углубления своих знаний.
- Понимание перегрузки функций в Python. Этот текст на Medium подскажет вам более тонкие детали перегрузки функций.
- Учебник по перегрузке функций | DigitalOcean. Пройдите по этому подробному практическому руководству, чтобы освоить тему.