Default Parameters
Sometimes a parameter has an obvious usual value. A rate of interest is nearly always 6.5%; a greeting is nearly always “Good morning”. A default parameter lets the definition supply that value itself, so the caller only has to mention it when it is different.
1Giving a parameter a default
def greet(name, message='Good morning'):
print(message + ',', name)
greet('Riya') # message is left out
greet('Amit', 'Good evening') # message is suppliedGood morning, Riya Good evening, Amit
The = in the definition is what makes it a default. Read it as “if nobody tells me, use this”. The first call passes one argument and the second passes two, and both are legal calls of the same function.
message always has a value — either the one the caller gave or the one the definition provides. The body never has to check.2Several defaults at once
def interest(principal, rate=6.5, years=1):
return principal * rate * years / 100
print(interest(20000)) # rate 6.5, years 1
print(interest(20000, 7.5)) # rate 7.5, years 1
print(interest(20000, 7.5, 3)) # all three supplied1300.0 1500.0 4500.0
One function, three sensible ways to call it. Arguments still fill the parameters left to right, so supplying two means you have set principal and rate — there is no way to skip rate and set only years this way.
3Defaults must come last
This is the rule the exam asks about, and it follows from positional matching rather than from any decision of Python's:
def f(a=1, b):
pass File "default_order_error.py", line 1
def f(a=1, b):
^
SyntaxError: parameter without a default follows parameter with a defaultf(a=1, b), a call of f(5) is ambiguous: is the 5 filling a, leaving b empty — or is it meant for b? Python refuses the definition rather than guess at the call. So: all parameters without defaults first, all parameters with defaults after them.def f(a, b)
def f(a, b=2)
def f(a, b=2, c=3)
def f(a=1, b=2)def f(a=1, b)
def f(a, b=2, c)
def f(a=1, b, c=3)4Skipping one: name it at the call
To set years without touching rate, name the argument at the call. Python then matches by name instead of position:
def interest(principal, rate=6.5, years=1):
return principal * rate * years / 100
print(interest(20000, years=3)) # rate stays at 6.5
print(interest(principal=20000, years=3, rate=7.5)) # order no longer matters3900.0 4500.0
These are keyword arguments. Notice the second call lists them in a different order from the definition and still works — because once you name them, position has nothing left to decide. Named arguments must come after any positional ones.
5The one trap worth knowing
A default value is worked out once, when the def line runs — not afresh on every call. With a number or a string you would never notice. With a list you will:
def add_item(item, basket=[]):
basket.append(item)
return basket
print(add_item('pen'))
print(add_item('book'))
print(add_item('bag'))['pen'] ['pen', 'book'] ['pen', 'book', 'bag']
Three separate calls, each expecting a fresh basket, all sharing one list — the one created when the function was defined. The fix is to default to None and make the real list inside:
def add_item(item, basket=None):
if basket is None:
basket = []
basket.append(item)
return basket
print(add_item('pen'))
print(add_item('book'))['pen'] ['book']
True, False and None are all safe, because none of them can be changed in place. This is the mutable / immutable distinction from Class 11 showing up in a third place.6Recap
def greet(name, message='Good morning'). It means 'if nobody tells me, use this'.
SyntaxError: parameter without a default follows parameter with a default — because f(5) would otherwise be ambiguous.
interest(20000, years=3) leaves rate at its default. Named arguments come after positional ones.
The default is made once, at def time, and every call shares it. Default to None and build the list inside.
- 1
Write
area(length, breadth=1)and call it both ways.Hint ·
area(5)gives 5 andarea(5, 3)gives 15 — a default of 1 turns it into a length. - 2
Write
def f(a=1, b)deliberately and read the error.Hint · Worth seeing once, so the wording is familiar when it happens for real.
- 3
Write a function with three parameters, two of them defaulted, and call it four different ways.
Hint · One argument, two, three, and one using a keyword argument to skip the middle parameter.
- 4
Run the
basket=[]example, then fix it withbasket=None.Hint · The first grows across calls; the second starts empty each time. Seeing both is the point.
Why is `def f(a=1, b):` a SyntaxError?
What does interest(20000, years=3) do to rate?
Why does `def add_item(item, basket=[])` grow across separate calls?