Typing *args and **kwargs
*args
and **kwargs
is a feature of python that lets you pass any number of
arguments and keyword arguments to a function (that's what the name args
and
kwargs
stands for, but these names are just convention, you can name the
variables anything).
All the extra arguments passed to *args
get turned into a tuple, and kewyord
arguments turn into a dictionay, with the keys being the string keywords:
def i_can_take_any_values(first_arg, *args, **kwargs):
print('got extra args:', args)
print('got kwargs:', kwargs)
i_can_take_any_values(1, 16, 'Hello', x=False, answer=42)
Since the *args
will always be of type Tuple[X]
, and **kwargs
will always
be of type Dict[str, X]
, we only need to provide one type X
to be able to
define their type. Here's a practical example, that takes keywords of marks in a
subject, and creates a Scorecard
:
class Scorecard:
def __init__(
self,
english: int | None,
maths: int | None,
physics: int | None
) -> None:
self.english = english
self.maths = maths
self.physics = physics
def build_scorecard(**marks: int) -> Scorecard:
card = Scorecard(
english=marks.get('english'),
maths=marks.get('maths'),
physics=marks.get('physics'),
)
return card
marks = {'english': 55, 'physics': 84}
scorecard = build_scorecard(**marks)
print(scorecard.physics)
print(scorecard.maths)
To verify, you can use reveal_type
:
def build_scorecard(**marks: int) -> None:
reveal_type(marks)
marks
is indeed dict[str, int]
.