Когда я пытаюсь обойтись без *args
и **kwargs
в сигнатурах функций, это не всегда можно сделать, не вредя удобству использования API. Особенно — когда надо писать функции, которые обращаются к вспомогательным функциям с одинаковыми сигнатурами.
Типизация *args
и **kwargs
всегда меня расстраивала, так как их нельзя было заблаговременно снабдить точными аннотациями. Например, если и позиционные, и именованные аргументы функции могут содержать лишь значения одинаковых типов, можно было поступить так:
def foo(*args: int, **kwargs: bool) -> None:
...
Применение такой конструкции указывает на то, что args
— это кортеж, все элементы которого являются целыми числами, а kwargs
— это словарь, ключи которого являются строками, а значения имеют логический тип.
Но нельзя было адекватно аннотировать *args
и **kwargs
в ситуации, когда значения, которые можно передавать в качестве позиционных и именованных аргументов, могут, в разных обстоятельствах, относиться к различным типам. В таких случаях приходилось прибегать к Any
, что противоречило цели типизации аргументов функции.