Default and keyword arguments
Default values
A parameter can have a default value, used when the caller doesn't pass that argument:
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Asha")
greet("Leo", "Good morning")Parameters with defaults must come after those without them. def greet(greeting="Hello", name): is a syntax error.
def power(base, exponent=2):
return base ** exponent
print(power(5)) # 25
print(power(5, 3)) # 125You have already used defaults in built-in functions: print()'s sep=" " and end="\n", and round()'s ndigits.
Keyword arguments
When calling, you can name the parameter you're giving a value to. Keyword arguments can be in any order:
def describe_pet(animal, name, age=1):
print(f"{name} the {animal} is {age} year(s) old.")
describe_pet(animal="cat", name="Mittens")
describe_pet(name="Rex", age=4, animal="dog")
describe_pet("parrot", age=12, name="Polly")Keyword arguments make calls self-explanatory: send_email(to="mei@example.com", urgent=True) is far clearer than send_email("mei@example.com", True).
Positional arguments must come before keyword arguments in a call:
def f(a, b):
print(a, b)
f(b=2, 1)The mutable default trap
Default values are created once, when the function is defined, not each time it's called. With a list as a default, every call shares the same list:
def add_item(item, basket=[]):
basket.append(item)
return basket
print(add_item("apple"))
print(add_item("pear")) # the apple is still there!The fix is to default to None and create the list inside:
def add_item(item, basket=None):
if basket is None:
basket = []
basket.append(item)
return basket
print(add_item("apple"))
print(add_item("pear"))Use None as the default for lists, dictionaries and sets, every time.
Keyword-only parameters
Parameters after a * must be passed by keyword. This forces callers to be explicit about settings:
def connect(host, *, timeout=10, secure=True):
print(f"Connecting to {host} (timeout={timeout}, secure={secure})")
connect("example.com", timeout=5)