Where a Name Lives
A name created inside a function exists only inside that function, and it disappears when the function finishes. This rule is called scope, and it is what lets a hundred functions in one program each use a name like total without ever stepping on one another. It also leads to a simple habit that keeps functions honest.
Think of a hotel room. What you leave in your room is yours, and it is cleared out when you check out. The lobby is shared by every guest, which is exactly why you do not keep your things there.
Local Names
A name assigned inside a function is local to it. It is created when the function runs and gone when it returns. Outside the function, it does not exist. In the program below, total is created inside average. Asking for it afterwards, outside the function, is a NameError: as far as the rest of the program is concerned, there never was a total.
def average(values): total = sum(values) return total / len(values) print(average([18, 22, 25])) print(total)
21.666666666666668
Traceback (most recent call last):
File "/Users/you/python-course/local.py", line 6, in <module>
print(total)
^^^^^
NameError: name 'total' is not defined
The fix is not to reach inside the function but to use what it returns. The average came back out through return; that is the only door.
Reading an Outside Name
A function can read a name created at the top level of the file, outside every function. That is convenient, and it has a cost: the function now quietly depends on something it did not ask for. Read it on its own and you cannot tell what it needs.
BOILING = 100 def is_boiling(celsius): return celsius >= BOILING print(is_boiling(104))
True
A fixed value like this, written in capitals by convention, is a reasonable thing to read from outside, because it never changes. A value that changes is a different matter, as the next section shows.
Changing an Outside Name Does Not Work the Way It Looks
Assigning to a name inside a function always creates a local name, even if a name with the same spelling exists outside. The outside one is left untouched. In the program below, reset sets its own local count to zero, and the count outside is still 7 afterwards.
count = 7 def reset(): count = 0 reset() print(count)
7
Try to change the outside name using its own value, as in count = count + 1, and Python refuses: the name is local, because it is assigned in the function, but it has no value yet when the right-hand side is worked out.
count = 7 def add_one(): count = count + 1 add_one()
Traceback (most recent call last):
File "/Users/you/python-course/unbound.py", line 6, in <module>
add_one()
~~~~~~~^^
File "/Users/you/python-course/unbound.py", line 4, in add_one
count = count + 1
^^^^^
UnboundLocalError: cannot access local variable 'count' where it is not associated with a value
Python does have a keyword, global, that lets a function change an outside name, and this book does not use it. The better habit is the one in the next section.
Parameters In, return Out
Give a function what it needs as parameters, and hand back what it makes with return. Then a function is a sealed box: the same inputs always give the same output, and nothing outside changes behind your back. The counter above becomes a function that takes the old count and returns the new one, and the caller decides what to do with it.
def add_one(count): return count + 1 count = 7 count = add_one(count) print(count)
8
- "A name set inside a function is available after it runs." It disappears when the function returns. Hand it back with return and store the result.
- "Assigning to an outside name inside a function changes it." It creates a separate local name. The outside one keeps its value.
- "Globals are simpler." They are simpler for five minutes. After that, every function that touches one has to be understood together with every other.
- Local names are why large programs stay understandable: each function can be read, and trusted, on its own.
- "Parameters in, return out" is the habit that makes Chapter 12's automated tests possible.
Knowledge Check
After a function that sets total = 0 inside it has run, what does print(total) outside it do?
- Prints 0, the value the function set
- Raises a NameError, unless total also exists outside
- Prints None, because the function has finished
- Prints the last value total had anywhere
With count = 7 outside, what does a function containing count = 0 do to the outside count?
- Nothing: it makes its own local count, and 7 stays
- Sets the outside count to 0 as soon as it is called
- Raises an error, because the name is already taken
- Deletes the outside count, so it no longer exists
What is the habit this page recommends for functions?
- Keep shared values at the top so any function can change them
- Use the global keyword whenever a value must change
- Print results inside the function instead of returning them
- Take inputs as parameters and hand results back with return
What does UnboundLocalError mean in count = count + 1 inside a function?
- The name count was never created anywhere in the file
- count is local here, and has no value when the right side is read
- Python cannot add one to a number inside a function
- The function was called before it was defined further down the file
You got correct