
Scope in Python determines the visibility and accessibility of variables, functions, and objects in different parts of your code. Proper understanding of scope is crucial for writing clean, efficient, and bug-free Python programs. Let’s explore Python’s scope rules with practical examples.
Types of Scope in Python
Python has four types of scope:
- Local scope – Variables defined inside a function
- Enclosing scope – Variables in the scope of enclosing functions (in nested functions)
- Global scope – Variables defined at the top level of a module or declared global
- Built-in scope – Names reserved by Python (like
print
,len
, etc.)
1. Local Scope Example
Variables defined inside a function have local scope – they’re only accessible within that function.
def greet():
message = "Hello, World!" # Local variable
print(message)
greet() # Output: Hello, World!
print(message) # Error: NameError: name 'message' is not defined
2. Global Scope Example
Variables defined outside any function have global scope.
global_var = "I'm global"
def show_global():
print(global_var) # Accessing global variable
show_global() # Output: I'm global
print(global_var) # Output: I'm global
3. Modifying Global Variables
To modify a global variable inside a function, you need to use the global
keyword.
count = 0
def increment():
global count
count += 1
print(f"Inside function: {count}")
increment() # Output: Inside function: 1
print(f"Outside function: {count}") # Output: Outside function: 1
Without the global
keyword, Python would create a new local variable instead:
count = 0
def increment():
count = 100 # This creates a new local variable
print(f"Inside function: {count}")
increment() # Output: Inside function: 100
print(f"Outside function: {count}") # Output: Outside function: 0
4. Enclosing (Nonlocal) Scope Example
In nested functions, the nonlocal
keyword allows you to modify variables from the enclosing scope.
def outer():
x = "local"
def inner():
nonlocal x
x = "nonlocal"
print("Inner:", x)
inner()
print("Outer:", x)
outer()
# Output:
# Inner: nonlocal
# Outer: nonlocal
Without nonlocal
, the inner function would create a new local variable:
def outer():
x = "local"
def inner():
x = "new local" # This creates a new local variable
print("Inner:", x)
inner()
print("Outer:", x)
outer()
# Output:
# Inner: new local
# Outer: local
5. Built-in Scope Example
Python’s built-in names are always available but can be overridden.
# Using built-in scope
numbers = [1, 2, 3]
print(len(numbers)) # Output: 3 (using built-in len() function)
# Overriding built-in
len = 10 # This shadows the built-in len
print(len) # Output: 10
# To restore access to built-in len, delete the variable
del len
print(len(numbers)) # Output: 3 (built-in len accessible again)
Scope Resolution Order (LEGB Rule)
Python follows the LEGB rule when looking up names:
- Local – Names assigned in any way within a function
- Enclosing – Names in the local scope of enclosing functions
- Global – Names assigned at the top-level of a module
- Built-in – Names preassigned in Python
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x) # local
inner()
print(x) # enclosing
outer()
print(x) # global
Best Practices for Scope Management
- Avoid modifying global variables inside functions when possible
- Use descriptive variable names to avoid shadowing built-ins
- Keep functions small to minimize scope complexity
- Use
global
andnonlocal
keywords sparingly - Prefer returning values from functions rather than modifying external state
Understanding Python scope helps prevent bugs related to variable access and modification, and leads to cleaner, more maintainable code. The LEGB rule provides a clear framework for determining where Python will look for variable definitions.