Python Tutorial › Functions › Scope

Python Scope

IntermediateLesson 26 of 479 min read8 runnable examples

Scope decides where a name can be seen. A variable created inside a function exists only inside that function, while a variable created at the top of a file can be read everywhere. Understanding scope explains several confusing errors.

Advertisement
In this lesson
  • Local and global variables
  • The LEGB lookup rule
  • When to use global and nonlocal
  • Closures that remember values

Local scope

A variable assigned inside a function is local: it is created when the function runs and disappears when it returns.

Python
def make_report():    title = "Daily report"     # local    print(title) make_report()print(title)
Output
Daily report
Traceback (most recent call last):
  File "main.py", line 6, in <module>
    print(title)
          ^^^^^
NameError: name 'title' is not defined. Did you mean: 'tuple'?

Global scope

A variable assigned at the top level of a file is global. Functions can read it.

Python
BASE_URL = "https://sqatools.in" def page_url(path):    return BASE_URL + path      # reading a global is fine print(page_url("/python-tutorials/"))
Output
https://sqatools.in/python-tutorials/

Same name, different variables

Assigning inside a function creates a new local variable, even if a global has the same name. The global is untouched.

Python
count = 10 def reset():    count = 0                   # a new local count    print("inside:", count) reset()print("outside:", count)
Output
inside: 0
outside: 10

The LEGB rule

When Python looks up a name, it searches four scopes in order and uses the first match:

OrderScopeExample
LLocal: the current functionvariables assigned in the function
EEnclosing: outer functionsvariables of a function that contains this one
GGlobal: the moduletop-level variables and functions
BBuilt-inprint, len, max
Python
x = "global" def outer():    x = "enclosing"    def inner():        print(x)          # not local, found in the enclosing function    inner() outer()print(len("built-in lookup"))
Output
enclosing
15

The global keyword

To assign to a global variable inside a function, declare it with global:

Python
counter = 0 def increment():    global counter    counter += 1 increment()increment()print(counter)
Output
2
Watch out

Functions that change globals are hard to test and reason about. Prefer passing values in and returning results: counter = increment(counter).

UnboundLocalError

If a function assigns to a name anywhere, that name is local for the whole function. Reading it before the assignment fails:

Python
total = 100 def add_tax():    total = total * 1.18      # total is local here, but has no value yet    return total add_tax()
Output
Traceback (most recent call last):
  File "main.py", line 7, in <module>
    add_tax()
    ~~~~~~~^^
  File "main.py", line 4, in add_tax
    total = total * 1.18      # total is local here, but has no value yet
            ^^^^^
UnboundLocalError: cannot access local variable 'total' where it is not associated with a value

The fix is to pass the value in: def add_tax(total): return total * 1.18.

nonlocal and closures

nonlocal lets an inner function assign to a variable of its enclosing function. The inner function keeps that variable alive even after the outer function has returned. This is called a closure.

Python
def make_counter():    count = 0    def next_value():        nonlocal count        count += 1        return count    return next_value ticket = make_counter()print(ticket(), ticket(), ticket()) other = make_counter()        # a separate countprint(other())
Output
1 2 3
1

Closures are useful for creating customised functions:

Python
def make_multiplier(factor):    def multiply(x):        return x * factor    return multiply double = make_multiplier(2)triple = make_multiplier(3)print(double(5), triple(5))
Output
10 15

Check your understanding

Predict the output

x = 1def f():    x = 2    def g():        nonlocal x        x = 3    g()    return xprint(f(), x)

Quick quiz

1. In what order does Python look up a name?

2. What is needed to change a module-level variable inside a function?

3. Why does UnboundLocalError happen?

Exercise: running average

Write make_averager() that returns a function. Each call adds a number and returns the average so far.

Input
10, then 20, then 60
Expected output
10.0 15.0 30.0
Hint 1

Keep total and count in the outer function and use nonlocal.

Program Practice

Python scope FAQ

What is the difference between local and global variables in Python?

A local variable is created inside a function and exists only while it runs. A global variable is created at the top level of a module and can be read anywhere in it.

When should I use the global keyword?

Rarely. Use it only when a function really must rebind a module-level variable. Passing values in and returning results is usually clearer.

What does nonlocal do in Python?

It lets a nested function assign to a variable of the enclosing function instead of creating a new local one.

Leave a Comment