Introduction
Functions get much more flexible once parameters can have default values and arguments can be given by name. This lesson also answers a question that confuses many beginners: when a function uses a variable name, which variable is it?
Real functions often have options that most callers do not need to think about. Defaults make the common case short, and understanding which variable a name refers to prevents a whole family of confusing errors.
How it works
Local and global variables
count = 10
def bump(count):
count = count + 1
return count
result = bump(count)
print(count, result)Watch the frames panel. The global frame has count = 10. When bump is called, its own frame gets a separate count, and line 4 changes only that one: count + 1 → 10 + 1 → 11. When bump returns, its frame disappears and the global count is still 10. The output is 10 11.
A variable created inside a function is local: it lives in that call's frame and nowhere else.
A classic error
total = 0
def add_to_total(x):
total = total + x
return total
add_to_total(5)Because add_to_total assigns to total, Python treats total as a local variable for the whole function. On line 4 it tries to read that local before it has a value, and raises UnboundLocalError. The fix is to pass the value in and return the result: total = add_to_total(total, 5).
Syntax
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
greet("Mitu")
greet("Mitu", "Welcome")
greet(greeting="Hi", name="Mitu")
Example
def greet(name, greeting="Hello"):
return greeting + ", " + name + "!"
print(greet("Rahim"))
print(greet("Nadia", "Welcome"))
print(greet(greeting="Hi", name="Karim"))greeting="Hello" gives the parameter a default value, used when the caller leaves it out. Step through the three calls:
greet("Rahim")uses the default, and the calculation box shows'Hello' + ', ' + 'Rahim' + '!' → 'Hello, Rahim!'.greet("Nadia", "Welcome")replaces the default.greet(greeting="Hi", name="Karim")names each argument, so the order no longer matters. These are keyword arguments.
Parameters with defaults must come after the ones without.
Line by line
def greet(name, greeting="Hello"):gives the second parameter a default.greet("Rahim")leaves it out, so"Hello"is used.greet("Nadia", "Welcome")replaces the default.greet(greeting="Hi", name="Karim")names both arguments, so their order does not matter.
Expected result
Hello, Rahim!
Welcome, Nadia!
Hi, Karim!
In the real world
Library functions often have many options with sensible defaults. sorted(items, reverse=True) is one you have already met, and it is far clearer than a bare True with no name.
Common mistakes
- Putting a default parameter before a normal one:
def f(a=1, b):is aSyntaxError. - Expecting a function to change a global number. Return the new value instead and assign it outside.
- Using a list as a default value:
def f(items=[])shares one list between all calls. Useitems=Noneand create the list inside.
Best practices
- Name arguments when a call would otherwise be unclear.
- Use
Noneas the default for lists and dictionaries. - Pass values in and return results, rather than using globals.
Summary
Default values make arguments optional, and keyword arguments can be given in any order. Variables created inside a function are local to that call, and a mutable default is shared between calls.
Practice
Write def power(base, exp=2) that returns base ** exp. Check that power(5) is 25 and power(2, 10) is 1024, then step through both calls.
Quick check
Key takeaways
- Parameters with defaults come last.
- A function that assigns to a name makes it local.
- Return new values instead of changing globals.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.