Function arguments in Python: defaults and keywords
Most sales are 30% off. Clearance is 50%. Writing two functions for that would be silly, and so would typing 0.3 every time. Default and keyword arguments solve both.
The big idea
A parameter can have a default value that's used when the caller omits it, and any argument can be passed by name.
See it in code
Give a parameter a default with = in the def line. A caller can now leave that argument out:
def sale_price(price, discount=0.3):
return round(price * (1 - discount), 2)
print("Sale price:", sale_price(38))Sale price: 26.6
Only price was passed, so discount took its default of 0.3. The most common case is now the shortest call.
To override a default, name the parameter in the call. That's a keyword argument, and it documents itself:
def sale_price(price, discount=0.3):
return round(price * (1 - discount), 2)
print("Sale price:", sale_price(38))
print("Clearance price:", sale_price(38, discount=0.5))Sale price: 26.6 Clearance price: 19.0
sale_price(38, discount=0.5) reads like a sentence. Compare sale_price(38, 0.5), where the reader has to remember what the second number means.
With several parameters, keywords make a call hard to get wrong. They can come in any order, and defaults fill in whatever you skip:
def forecast(start_units, growth, months, price=38):
units = start_units
total = 0
for month in range(months):
total = total + units * price
units = round(units * (1 + growth))
return total
print(f"Base plan: ${forecast(300, 0.15, 12):,}")
print(f"Cautious plan: ${forecast(months=12, growth=0.10, start_units=300, price=36):,}")Base plan: $331,398 Cautious plan: $230,724
The second call lists its arguments in a completely different order, and it still works, because each one is matched by name, not position.
This is how well-designed tools feel. Sensible defaults for the common case, named options for the rest: the same idea behind sorted(data, reverse=True) and print(x, end="").
Try it yourself
Call forecast(300, 0.15, 12, price=42) and compare it with the base plan. Then change the default discount in sale_price to 0.25 and see which calls change and which don't.
The common mistake
Putting a parameter without a default after one that has one. def sale_price(discount=0.3, price): is a syntax error. Required parameters come first, optional ones after.
What it unlocks
Arguments are how values get into a function; return values are how results get out. A function call can also be an argument itself, which is how functions compose.