Python for Programmers: Default Argument Values
Welcome to the Default Argument Values lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
When we call a function, we have to pass the correct number of arguments. If we forget an argument, that's an error.
>
def greet(name, excited):punctuation = ("!" if excited else ".")return f"Hello {name}{punctuation}"greet("Amir")Result:
TypeError: greet() missing 1 required positional argument: 'excited'
Sometimes we want to make an argument optional. The next example makes
excitedoptional, defaulting toFalse. Note the difference in thedefline.>
def greet(name, excited=False):punctuation = ("!" if excited else ".")return f"Hello {name}{punctuation}"- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
greet("Amir")Result:
'Hello Amir.'
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
greet("Betty", True)Result:
'Hello Betty!'
The default argument syntax may remind you of the kwarg syntax. They both concern function arguments and they both use
=.Despite their similar syntax, these language features are separate. We specify default argument values with
arg_name=default_valuewhen defining a function, as shown above. We provide kwargs witharg_name=some_valuewhen calling a function.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
greet("Cindy", excited=True)Result:
'Hello Cindy!'
Although default arguments and kwargs are two different language features, they do tend to show up together. It's considered good style to use kwargs when overriding a default argument value. This makes it clear that we're doing something unusual.
For example, when we see a call like
greet("Cindy", True), it doesn't show us that we're overriding a default argument. But when we seegreet("Cindy", excited=True), the kwarg suggests that something unusual is happening.This is even more important when functions have multiple default arguments. For example, we can expand our
greetfunction to take three arguments, two of which are optional.>
greetings = {"en": "Hello","fr": "Bonjour"}def greet(name, excited=False, language="en"):greeting = greetings[language]punctuation = ("!" if excited else ".")return f"{greeting} {name}{punctuation}"- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
greet("Amir")Result:
'Hello Amir.'
We have a lot of flexibility when calling functions like this. In the next example, we pass a value for the first argument (
name), we omit the second argument (excited), and we pass a value for the third argument (language). This is perfectly legal, even though we left out the middle argument!- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
greet("Amir", language="fr")Result:
'Bonjour Amir.'
Here's a code problem:
This
get_cat(owner_name)function returns the cat owned by that owner. Modify the function to work when we don't pass anowner_nameat all, by givingowner_namea default value of"Unknown".cats = {"Amir": "Ms. Fluff","Betty": "Keanu","Wilford": "Wilford","Unknown": "No cat"}def get_cat(owner_name="Unknown"):return cats[owner_name]assert get_cat("Betty") == "Keanu"assert get_cat() == "No cat"- Goal:
No errors.
- Yours:
No errors.
Default arguments can seem simple at first, but there's one important catch, which has led to many subtle bugs in real-world systems. The question is: when does Python evaluate the default value? Try to guess what value we get in the next example.
>
default_value = 3# When is the default value evaluated? Once, when the function is defined? Or# each time the function is called?def f(x=default_value):return xdefault_value = 4f()Result:
3
There are two possible ways for that code to work, both of which make some sense:
- The default value expression is evaluated only once, when the function is defined.
If
default_valuechanges later,x's default value is still 3. This is how Python works. - The default value expression is evaluated every time the function is called.
If
default_valuechanges, and we then call the function,xgets the new value of 4. This is how JavaScript and Ruby work.
- The default value expression is evaluated only once, when the function is defined.
If
If you're used to (2) above, it's important to remember that Python actually works like (1)! This will help you avoid subtle, frustrating bugs.
To reiterate, here are side-by-side versions of the function in Python and JavaScript, showing their different behavior.
>
# This is Python.default_value = 3def f(x=default_value):return xdefault_value = 4f()Result:
>
/* This is JavaScript, not Python! */
let default_value = 3;
function f(x=default_value) {
return x;
}
default_value = 4;
f();Result: