Please see the code below:-
# Filename: total.py
def total(initial=5, *numbers, **keywords):
count = initial
for number in numbers:
count += number
for key in keywords:
count += keywords[key]
print(total(10, 1, 2, 3, vegetables=50, fruits=100))
In your code
numbers is assigned to the (1,2,3) tuple.
keywords is assigned to a dictionary, containing
One star '*' defines positional arguments. This means that you can receive any number of arguments. You can treat the passed arguments as a tuple.
Two stars '**' define keywords arguments.
The reference material is available here.
Python 2.x (before keyword-only arguments)
def foo(x, y, foo=None, *args): print [x, y, foo, args] foo(1, 2, 3, 4) --> [1, 2, 3, (4, )] # foo == 4 foo(1, 2, 3, 4, foo=True) --> TypeError
Python 3.x (with keyword-only arguments)
def foo(x, y, *args, foo=None): print([x, y, foo, args]) foo(1, 2, 3, 4) --> [1, 2, None, (3, 4)] # foo is None foo(1, 2, 3, 4, foo=True) --> [1, 2, True, (3, 4)] def combo(x=None, *args, y=None): ... # 2.x and 3.x styles in one function
Although a seasoned programmer understands what happened in 2.x, it's counter-intuitive (a positional argument gets bound to
foo= regardless of keyword arguments as long as there are enough positional arguments)
Python 3.x introduces more intuitive keyword-only arguments with PEP-3102 (keyword arguments after varargs can only be bound by name)