The * and ** operators are used in two different situations.
-
When used as part of a function definition,
def save_name_for(self, *args, **kwargs):it is used to signify an arbitrary number of positional or keyword
arguments, respectively. The point to remember is that inside the
functionargswill be a tuple, andkwargswill be a
dict. -
When used as part of a function call,
args = (1, 2) kwargs = {'last': 'Doe', 'first': 'John'} self.save_name_for(*args, **kwargs)the
*and**act as unpacking operators.argsmust be an
iterable, andkwargsmust be dict-like. The items inargs
will be unpacked and sent to the function as positional arguments,
and the key/value pairs inkwargswill be sent to the function as
keyword arguments. Thus,self.save_name_for(*args, **kwargs)is equivalent to
self.save_name_for(1, 2, last="Doe", first="John")
See also the saltycrane blog for an explanation with examples.