Интересные заметки и обучающие материалы по Python
Контакт: @paulwinex
⚠️ Рекламу на канале не делаю!⚠️
Хештеги для поиска:
#tricks
#libs
#pep
#basic
#regex
#qt
#django
#2to3
#source
#offtop
Post #284
2.18K
Наверняка вы знаете что такое перегруженная функция в С++. Если нет, то всё просто.
В С++ можно создать несколько функций с одинаковым названием но разными типами аргументов. И это будут разные функции.
Во время вызова функции будет выбрана та её версия которая подходит по типам аргументов. Такая конструкция называется параметрический полиморфизм.
Это удобно, когда мы точно не знаем какого типа прилетит аргумент и хотим обработать разные ситуации.
Как мы это поведение можем повторить в Python? Обычно через проверку типов.
Начиная с версии 3.4 в Python добавили способ делать "перегруженные" функции более элегантно. Это декоратор singledispatch.
Создадим нашу исходную функцию которая по умолчанию выбрасывает ошибку.
В качестве аргумента указывайте тип который данная функция обрабатывает
Имя новой функции не имеет значения, часто её называют просто "_"
◽️ Данный способ работает только с первым аргументом. Все остальные аргументы будут переданы как есть и не участвуют в выборе нужной функции.
◽️ В версии 3.8 доступен декоратор
#tricks #libs
В С++ можно создать несколько функций с одинаковым названием но разными типами аргументов. И это будут разные функции.
Во время вызова функции будет выбрана та её версия которая подходит по типам аргументов. Такая конструкция называется параметрический полиморфизм.
Это удобно, когда мы точно не знаем какого типа прилетит аргумент и хотим обработать разные ситуации.
Как мы это поведение можем повторить в Python? Обычно через проверку типов.
def func(value):Не очень красиво 🧐
if isinstance(value, int):
return func_int(value)
elif isinstance(value, str):
return func_str(value)
else:
raise NotImplementedError
Начиная с версии 3.4 в Python добавили способ делать "перегруженные" функции более элегантно. Это декоратор singledispatch.
Создадим нашу исходную функцию которая по умолчанию выбрасывает ошибку.
@singledispatchДекоратор добавил для объекта
def func(value)
raise NotImplementedError
func новую функцию register() с помощью которой можем регистрировать перегруженные функции.В качестве аргумента указывайте тип который данная функция обрабатывает
@func.register(int)Вместо указания типа в аргументах можно использовать аннотации аргумента функции
def func_int(x):
print("INT:", x)
@func.registerЕсли не указать тип одним из этих способов то получите ошибку TypeError.
def func_str(x: str):
print("STR:", x)
Имя новой функции не имеет значения, часто её называют просто "_"
@func.register(list)Если одна функция должна обработать несколько типов, то просто наслаиваем декоратор
def _(x):
print("LIST", x)
@func.register(float)Теперь у нас есть 5 отдельных функций которые вызываются в зависимости от типа передаваемого аргумента. При этом всё выглядит логично и компактно. Обработка каждого случая находится в своей отдельной функции!
@func.register(Decimal)
def _(x):
print(f'{type(x).__name__.upper()}:', x)
>>> func(1)------
INT: 1
>>> func('Python')
STR: Python
>>> func(1.2)
FLOAT: 1.2
>>> func({})
NotImplementedError
◽️ Данный способ работает только с первым аргументом. Все остальные аргументы будут переданы как есть и не участвуют в выборе нужной функции.
◽️ В версии 3.8 доступен декоратор
singledispatchmethod с таким же функционалом но для методов класса.#tricks #libs


