Python programming
global variables
variable scope
programming concepts
Python keywords

Why isn't the 'global' keyword needed to access a global variable?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python, you do not need global just to read a global variable. You only need global when you want an assignment inside a function to target the module-level name instead of creating a new local name. That difference between reading and rebinding is the whole story.

Python’s Name Lookup Rules

When Python evaluates a name inside a function, it searches scopes in order:

  1. local
  2. enclosing
  3. global
  4. built-in

That lookup rule is often summarized as LEGB. Because global scope is already part of normal name lookup, a function can read a module-level variable without any special declaration.

python
1tax_rate = 0.13
2
3def total_with_tax(amount):
4    return amount * (1 + tax_rate)
5
6print(total_with_tax(100))

This works because tax_rate is only being read. Python looks for a local tax_rate, does not find one, and then finds the module-level name.

Why Assignment Changes the Rules

The moment you assign to a name anywhere in a function body, Python treats that name as local to that function unless you explicitly say otherwise.

That means this fails:

python
1count = 0
2
3def increment():
4    count += 1
5    return count

Python sees count += 1 and decides that count is a local variable inside increment. But the function tries to read that local value before it has been assigned, so you get an UnboundLocalError.

To tell Python that the assignment should target the module-level variable, you use global:

python
1count = 0
2
3def increment():
4    global count
5    count += 1
6    return count

Now the assignment and read both refer to the global count.

Reading Is Not the Same as Rebinding

This is the distinction many beginners miss:

  • reading a global name does not need global
  • rebinding a global name does need global

Rebinding means giving the name a new object. For example:

python
1config = {"debug": False}
2
3def enable_debug():
4    global config
5    config = {"debug": True}

Without global, that assignment would create a local config instead of replacing the global one.

Mutating a Global Object Is Different Again

There is another subtle case: mutating the object referenced by a global variable does not require global, because the name itself is not being rebound.

python
1items = []
2
3def add_item(value):
4    items.append(value)
5
6add_item("apple")
7print(items)

This works without global because items still points to the same list object. The function changes the contents of that list, not the binding of the name items.

That is why this distinction matters so much:

  • 'items.append(value) mutates the object'
  • 'items = [] rebinds the name'

Only the second form needs global inside a function.

Nested Functions Use nonlocal, Not global

If the variable lives in an enclosing function rather than at module scope, the keyword is nonlocal instead of global.

python
1def counter():
2    count = 0
3
4    def increment():
5        nonlocal count
6        count += 1
7        return count
8
9    return increment

That is a different scope rule, but it reinforces the main point: these keywords are about assignment targets, not about ordinary read access.

Common Pitfalls

The biggest pitfall is assuming global means “I want to use a global variable in this function.” In Python, ordinary reading already works. The keyword is specifically about rebinding.

Another common mistake is confusing mutation with assignment. Appending to a global list or updating a global dictionary does not need global, but replacing the list or dictionary does.

Developers also sometimes overuse global when a parameter or return value would be clearer. Even when global is technically correct, it can make code harder to reason about because hidden state spreads across functions.

Finally, if you see UnboundLocalError for a name that also exists globally, check whether the function assigns to that name anywhere. That assignment is what changes Python’s interpretation.

Summary

  • Python can read global names without global because global scope is part of normal name lookup.
  • 'global is required when a function rebinds a module-level name.'
  • Mutating a global object is different from rebinding the global name.
  • 'nonlocal handles the same idea for enclosing function scope.'
  • If a function both reads and assigns a name, Python treats it as local unless told otherwise.

Course illustration
Course illustration

All Rights Reserved.