Module lessons (3/4)
*args and **kwargs
Sometimes you want a function that accepts a variable number of
arguments. Python gives you two tools: *args (gathers positional arguments
into a tuple) and **kwargs (gathers keyword arguments into a dict).
*args: variable positional arguments
def somma_tutto(*nums):
totale = 0
for n in nums:
totale += n
return totale
somma_tutto(1, 2, 3) # 6
somma_tutto(1, 2, 3, 4, 5) # 15
somma_tutto() # 0Inside the function, nums is a tuple with all the values passed. The
name is just a convention: *args is the most common, but *nums or
*valori are perfectly valid.
**kwargs: variable keyword arguments
def crea_config(**opzioni):
return opzioni
crea_config(debug=True, port=8080)
# {'debug': True, 'port': 8080}Inside the function, opzioni is a dict with {param_name: value}.
Combining everything
The fixed order is: **regular parameters, *args, default parameters, **kwargs**.
def f(primo, *args, opzione="x", **kwargs):
print(primo, args, opzione, kwargs)
f(1, 2, 3, opzione="y", extra=10)
# 1 (2, 3) y {'extra': 10}Unpacking in the call: * and **
The same operator works the other way around: to "explode" a list/tuple into positional arguments or a dict into keyword arguments.
def punto(x, y, z):
return (x, y, z)
coords = [1, 2, 3]
punto(*coords) # punto(1, 2, 3) → (1, 2, 3)
opts = {"x": 1, "y": 2, "z": 3}
punto(**opts) # punto(x=1, y=2, z=3)Wrapper pattern
def log_chiamata(fn, *args, **kwargs):
print(f"chiamo {fn.__name__} con {args=} {kwargs=}")
return fn(*args, **kwargs)
log_chiamata(max, 3, 1, 2) # calls max(3, 1, 2)
log_chiamata(sorted, [3, 1, 2], reverse=True)Parameter ordering in function signatures
When defining a function that accepts multiple argument types, you must adhere to a strict order in the signature:
- Standard positional parameters.
- Positional varargs
*args. - Keyword parameters with default values.
- Keyword varargs
**kwargs.
Try it
Define `average(*nums)` that returns the arithmetic mean (sum / count). Call it with 10, 20, 30 and assign the result to `m`. Evaluate `m`.
Show hint
sum(nums) / len(nums)
Solution available after 3 attempts
Review exercise
Given the function `def point(x, y, z): return x + y + z` and the dict `coords = {'x': 1, 'y': 2, 'z': 3}`, call point unpacking coords and assign the result to `s`. Evaluate `s`.
Show hint
point(**coords)
Solution available after 3 attempts
Additional challenge
Write a function `multiply_all(*args)` that returns the product of all numbers passed as arguments. If no arguments are passed, it should return `1`. Finally, evaluate the call `multiply_all(2, 3, 4)`.
Show hint
Use a for loop to iterate over the elements in args and accumulate their product.
Solution available after 3 attempts