What’s New ?

The Top 10 favtutor Features You Might Have Overlooked

Read More
Python

Global and Local Variables in Python: Scope Explained

Jun 29, 2026 7 Minutes Read Why Trust Us Why you can trust this guide. Written by working engineers and reviewed by our editorial team under a strict editorial policy for accuracy, clarity and zero bias. Kaustubh Saini By Kaustubh Saini Kaustubh Saini Kaustubh Saini
I'm Kaustubh Saini, founder of FavTutor. I have a genuine passion for coding and data science. In my articles, I aim to break down complex topics, share coding insights, and make learning more accessible. When I'm not writing, I'm always exploring ways to enhance your learning experience at FavTutor.
Connect on LinkedIn →
Global and Local Variables in Python: Scope Explained

The first time a variable "disappears" on you, it feels like Python is playing a trick. You set a value inside a function, try to use it outside, and get an error saying the name doesn't exist. Nothing's broken. You've just run into scope, the set of rules that decides where each name in your code can be seen. A name you can reach from anywhere is a global variable, and a name that lives only inside one function is a local one.

Once you know these rules, a whole class of confusing bugs stops happening: values that won't update, names that vanish, errors that seem to come from nowhere. We'll go through local and global scope, the global and nonlocal keywords, and the order Python uses to track a name down. Every part has a small example you can run yourself.

What is scope?

Scope is the region of your program where a particular name can be used. The two you meet first are local scope, which lives inside a single function, and global scope, which is the top level of your file. A name you make in one scope isn't automatically available in another.

A global scope box containing a local scope box, showing global names are visible everywhere and local names only inside the function

Picture the function as a room. Whatever you put on a shelf inside that room only exists in that room. What sits out in the hallway is reachable from the hallway, and you can also see it by looking out from inside the room.

Local variables

A variable you assign inside a function is local to that function. It's born when the function runs and gone when the function ends. Code outside the function can't see it at all.

A function with a local variable that works inside, and a NameError when used outside the function
def greet():
    msg = "hi"
    print(msg)

greet()
print(msg)
# Output:
# hi
# NameError: name 'msg' is not defined

The print(msg) inside the function runs fine, but the one outside fails. That's because msg only existed while greet() was running. A local variable lives and dies with the function call. That's a feature, not a flaw, since it keeps each function self-contained and stops one function from quietly stepping on another's variables.

Global variables

A variable you define at the top level of your file, outside any function, is global. Any function can read it without doing anything special.

greeting = "Hello"

def welcome():
    print(greeting, "there")

welcome()
# Output: Hello there

Reading a global from inside a function is no trouble. The complication shows up when a function tries to change one, and that's exactly what the next section is about.

Why assigning to a global makes a local instead

Here's the part that surprises almost everyone. If a function assigns to a name, Python decides you mean a brand-new local variable, even when a global with the same name already exists.

count = 0

def add():
    count = count + 1   # error

add()
# UnboundLocalError: cannot access local variable 'count'

Because add() assigns to count, Python treats count as local to add() for the whole function. So when count + 1 tries to read it, there's no value there yet, and you get an UnboundLocalError. Assignment anywhere in a function makes that name local for the entire function. The fix is to tell Python you mean the global one.

The global keyword

To change a global variable from inside a function, declare it with the global keyword first. That line tells Python "use the existing outer variable, don't make a new local one".

A function using the global keyword so that assigning to count updates the outer global variable
count = 0

def add():
    global count
    count = count + 1

add()
add()
print(count)
# Output: 2

Reach for global sparingly, though. A function that quietly changes global state is harder to follow and harder to test, since you can't tell what it touches just by reading its call. Most of the time it's cleaner to return a value and let the caller decide what to update. The keyword's there for the cases where you genuinely need it.

How Python finds a name with the LEGB rule

When you use a name, Python searches scopes in a fixed order, which people remember as LEGB: Local first, then any Enclosing function, then Global, then Built-in. It stops at the first match it finds.

The LEGB lookup ladder: Local, then Enclosing, then Global, then Built-in
x = "global"

def outer():
    x = "enclosing"
    def inner():
        print(x)
    inner()

outer()
# Output: enclosing

The inner() function has no x of its own, so Python steps one level out, finds x = "enclosing", and uses that. If it weren't there either, Python would fall back to the global x, and after that to built-in names like print and len.

Enclosing scope and the nonlocal keyword

When you nest one function inside another, the inner one can read the outer function's variables. To change one of them, you use nonlocal. Think of it as the enclosing-scope cousin of global.

A nested function using nonlocal to update a variable in the enclosing function rather than a global one
def counter():
    n = 0
    def step():
        nonlocal n
        n = n + 1
        return n
    print(step())
    print(step())

counter()
# Output:
# 1
# 2

Without nonlocal, the assignment inside step() would spin up a fresh local n and the outer one would never move. With it, both calls update the same n in the enclosing function.

Functions, the place scope shows up

Scope only starts to matter once you're writing functions, so the two go hand in hand. As you keep going through the series you'll get into def, parameters, and return values properly. The short version is that a function is a named block of code you can run whenever you want.

def square(number):
    return number * number

print(square(5))
# Output: 25

Practice exercises

Run each one and check the output against your guess first.

Spot the local

Predict what this prints, then run it.

# Solution
def f():
    a = 5
    print(a)

f()
# Output: 5
# print(a) here would raise NameError

Update a global

Use global to add 10 to a global score from inside a function.

# Solution
score = 0

def boost():
    global score
    score = score + 10

boost()
print(score)
# Output: 10

Read an enclosing value

Make an inner function read a variable from the function around it.

# Solution
def outer():
    msg = "from outer"
    def inner():
        print(msg)
    inner()

outer()
# Output: from outer

Common mistakes

  • Assigning to a global without global. Python makes a local instead, which often gives you an UnboundLocalError.
  • Expecting a local to exist outside its function. It's gone the moment the function returns.
  • Leaning on global too much. Returning a value is usually cleaner; heavy global use makes code hard to follow.
  • Mixing up global and nonlocal. global targets the top level, while nonlocal targets an enclosing function.
  • Reusing a built-in name. Calling a variable list or sum hides the built-in inside that scope.

Frequently asked questions

What is the difference between local and global variables?

A local variable exists only inside the function that creates it and disappears when the function ends. A global variable is defined at the top level of the file and can be read from anywhere in it.

How do I change a global variable inside a function?

Declare it with global at the start of the function, then assign to it. Skip that and Python makes a separate local variable instead.

What is the LEGB rule?

It's the order Python searches for a name: Local, Enclosing, Global, Built-in. The first scope that has the name wins.

When should I use nonlocal?

Use it inside a nested function when you want to change a variable that belongs to the enclosing function, rather than make a new local or touch a global.

Why do I get UnboundLocalError?

A function assigns to a name, which makes it local, but then tries to read it before it has a value. If you meant the global, add global; if you meant an enclosing variable, use nonlocal.

Are global variables bad?

Not on their own, but leaning on them heavily makes code harder to test and reason about. Reading globals is common; changing them from many places is the part worth avoiding when a return value would do.

Key takeaways

  • Scope is where a name can be used, and the main kinds are local and global.
  • Variables made inside a function are local and vanish when the function ends.
  • Functions can read globals freely, but need the global keyword to change one.
  • Python resolves names with the LEGB order: Local, Enclosing, Global, Built-in.
  • Use nonlocal to update a variable in an enclosing function from a nested one.

Scope clicks into place once you've written a handful of your own functions and watched a few of these errors happen live. If any of the assignment or naming part still feels shaky, go back to the basics in Python variables, since scope is really just that same idea plus the question of where each name can be reached.

Kaustubh Saini
About the author

Kaustubh Saini

I'm Kaustubh Saini, founder of FavTutor. I have a genuine passion for coding and data science. In my articles, I aim to break down complex topics, share coding insights, and make learning more accessible. When I'm not writing, I'm always exploring ways to enhance your learning experience at FavTutor. Connect on LinkedIn →
Up nextPython Data Types and How to Use Them