intermediate

Default Parameter Values

Create functions with default parameter values.

Default parameters allow functions to be called with fewer arguments, making them more flexible and easier to use with sensible defaults.

📚 Concepts & Theory

Default parameters provide fallback values when arguments aren't supplied. This makes functions more flexible and user-friendly.

Basic Default Parameter:

def greet(name="World"):
return f"Hello, {name}!"

greet() # "Hello, World!" (uses default)
greet("Alice") # "Hello, Alice!" (overrides default)

Multiple Defaults:

def create_user(username, role="user", active=True):
return {
"username": username,
"role": role,
"active": active
}

create_user("alice") # All defaults
create_user("bob", "admin") # Override role
create_user("charlie", active=False) # Named override

Rules for Default Parameters:

1. Defaults Must Come After Required:

# ❌ WRONG - SyntaxError
def func(a=1, b):
pass

# ✅ CORRECT
def func(b, a=1):
pass

2. Evaluated Once at Definition:

def func(x=5):  # 5 is evaluated when function is defined
return x

3. Mutable Default Values - DANGER!

# ❌ DANGEROUS - Mutable default
def add_item(item, list=[]):
list.append(item)
return list

add_item(1) # [1]
add_item(2) # [1, 2] - UNEXPECTED! Same list object

# ✅ CORRECT - Use None
def add_item(item, list=None):
if list is None:
list = []
list.append(item)
return list

Common Patterns:

Configuration Functions:

def connect_db(host="localhost", port=5432, timeout=30):
# Connection logic
pass

API Calls:

def fetch_data(url, method="GET", timeout=10, headers=None):
if headers is None:
headers = {}
# Fetch logic

String Processing:

def process_text(text, lowercase=True, strip=True):
if lowercase:
text = text.lower()
if strip:
text = text.strip()
return text

Default from Expression:

import datetime

def log_message(msg, timestamp=None):
if timestamp is None:
timestamp = datetime.datetime.now()
print(f"[{timestamp}] {msg}")

Best Practices:

  • Use immutable defaults (numbers, strings, None, tuples)

  • Never use mutable defaults (lists, dicts, sets)

  • Defaults should be sensible, commonly-used values

  • Document default behavior in docstrings

🎯 Your Challenge

Create a function power(base, exponent=2) that raises base to the exponent (default 2 for square).

📝 Starter Code

Python
def power(base, exponent=2):
    pass
  • base is required, exponent is optional with default 2
  • Use the syntax: parameter=default_value
  • Default parameters must come after required ones
  • Return base raised to the exponent power
  • Use the ** operator for exponentiation

Solution

Python
def power(base, exponent=2):
    return base ** exponent

Explanation

This function demonstrates default parameters by making the exponent parameter optional with a default value of 2. When called as power(5), it uses the default exponent of 2 and returns 25 (5 squared). When called as power(5, 3), it overrides the default and returns 125 (5 cubed). The default parameter comes after the required parameter (base), which is mandatory. This pattern is common for operations where a default behavior (squaring) is most common, but flexibility is needed for other cases (cubing, etc.).

⚠️ Common Mistakes to Avoid

  • Putting default parameter before required parameter
  • Using mutable default values like lists
  • Not understanding that defaults are evaluated at function definition
  • Forgetting that all parameters after the first default must also have defaults
  • Calling with wrong parameter order

❓ Frequently Asked Questions

Yes! All parameters after the first default must also have defaults.
Yes! Call power(2, exponent=3) to explicitly set the exponent.
Mutable objects (lists, dicts) are shared between calls, causing unexpected side effects. Always use None and create new objects inside the function.
No! Default values are evaluated once when the function is defined, not each call.

🔗 Related Exercises