Default and Keyword Arguments
Giving parameters default values, calling functions with keyword arguments, and the *args/**kwargs pattern.
2 min read
Real functions often have parameters that are usually the same value, with the occasional need to override them. Python handles this cleanly with default arguments and named ("keyword") calls.
Default argument values
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Ada")) # Hello, Ada!
print(greet("Ada", "Welcome")) # Welcome, Ada!Any parameter with a = in the definition becomes optional — callers can omit it and get the default, or supply their own. Parameters with defaults must come after parameters without them in the definition; Python won't let you write def greet(greeting="Hello", name):.
A mutable default is a classic trap
# Avoid
def add_item(item, items=[]):
items.append(item)
return items
print(add_item("a")) # ['a']
print(add_item("b")) # ['a', 'b'] -- surprise! the same list persistedThe default list is created once, when the function is defined, not on every call — so every call that relies on the default shares and mutates the same list. The fix is to default to None and create the list fresh inside the function:
# Prefer
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return itemsThis is one of the most common gotchas for people new to Python — worth remembering even after everything else about default arguments feels natural.
Keyword arguments
Calling a function by naming its parameters lets you skip positional order and makes the call self-documenting:
def create_user(name, age, active=True):
return {"name": name, "age": age, "active": active}
user = create_user(name="Ada", age=25, active=False)You can mix positional and keyword arguments, but positional ones must come first: create_user("Ada", age=25) is valid; create_user(name="Ada", 25) is not.
*args and **kwargs
Sometimes you don't know how many arguments a function needs to accept ahead of time. *args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary:
def total(*args):
return sum(args)
print(total(1, 2, 3, 4)) # 10
def build_profile(**kwargs):
return kwargs
print(build_profile(name="Ada", age=25))
# {'name': 'Ada', 'age': 25}The names args and kwargs are convention, not a requirement — the * and ** are what matter — but sticking to the convention makes your code instantly recognizable to other Python developers.
Together, these tools let a function offer sensible defaults for the common case while staying flexible enough to handle the exceptions, without needing a dozen overloaded versions of the same function.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.