One of the most fundamental concepts in programming is scope — it defines the visibility and lifetime of variables. In Python, understanding how scope works is essential for writing clean, bug-free code.
In this tutorial, we’ll cover:
-
What is scope in Python?
-
The LEGB rule
-
Local, Enclosing, Global, and Built-in scopes
-
The
global
andnonlocal
keywords -
A complete code example
-
Tips and common pitfalls
What is Scope?
Scope refers to the region of a Python program where a particular variable is accessible. Python has several levels of scope that determine which variable names are visible and when.
The LEGB Rule
Python resolves variables using the LEGB rule, which stands for:
-
Local
-
Enclosing
-
Global
-
Built-in
Python checks for a variable name in this order.
1️⃣ Local Scope
Variables defined inside a function are in the local scope.
def my_function():
x = 10 # Local variable
print(x)
my_function() # Output: 10
# print(x) # Error: x is not defined (outside the local scope)
2️⃣ Enclosing Scope
This applies to nested functions. The inner function can access variables from the outer (enclosing) function.
def outer():
a = "outer"
def inner():
print(a) # Accessing enclosing variable
inner()
outer() # Output: outer
3️⃣ Global Scope
Variables defined at the top level of a script or module are in the global scope.
x = "global"
def show():
print(x)
show() # Output: global
4️⃣ Built-in Scope
These are names preassigned by Python. You can see them with dir(__builtins__)
.
print(len("Hello")) # 'len' is a built-in function
The global
Keyword
Use global
to modify a global variable inside a function.
Example:
count = 0
def increment():
global count
count += 1
increment()
print(count) # Output: 1
⚠️ Without global
, the above will raise an UnboundLocalError
.
The nonlocal
Keyword
Use nonlocal
to modify a variable in the enclosing (non-global) scope.
Example:
def outer():
num = 10
def inner():
nonlocal num
num += 5
print("Inner:", num)
inner()
print("Outer:", num)
outer()
# Output:
# Inner: 15
# Outer: 15
Complete Example: Scope in Action
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print("Inner:", x) # local scope
inner()
print("Outer:", x) # enclosing scope
outer()
print("Global:", x) # global scope
Output:
Inner: local
Outer: enclosing
Global: global
Tips for Mastering Scope
-
✅ Use local variables by default — they’re safer and more predictable.
-
✅ Use
global
sparingly — overusing global variables can make debugging harder. -
✅ Use
nonlocal
in nested functions only when necessary. -
✅ Stick to function arguments and return values instead of relying on external state.
⚠️ Common Pitfalls
Pitfall | Why It’s Problematic |
---|---|
❌ Modifying a global variable without global |
Causes UnboundLocalError |
❌ Assuming nested functions always inherit variable values | Without nonlocal , changes inside don’t affect enclosing variables |
❌ Shadowing built-in names (like list , str ) |
Can lead to confusing bugs |
❌ Overuse of global scope | Reduces modularity and testability |
Summary Table
Scope | Description | Defined In |
---|---|---|
Local | Inside a function | Function body |
Enclosing | In a nested function’s parent | Outer function |
Global | Top-level script/module | Module |
Built-in | Python's built-in names | __builtins__ module |
Understanding Python's scoping rules empowers you to write cleaner, more reliable, and modular code. Mastering local
, global
, enclosing
, and built-in
scopes will save you from subtle bugs and boost your confidence in building complex applications.