Python Variable Scope
In Python, variable scope determines where a variable can be accessed or modified within a program. Python follows the LEGB to resolve variable names.
The LEGB Rule
Python searches for variables in this order:
- Local – Inside the current function.
- Enclosing – In enclosing functions (for nested functions).
- Global – At the module level.
- Built-in – Python’s built-in names.
Local Scope
Variable defined inside a function are local to that function and cannot be accessed from outside of it.
For example:
def my_func():
x = 10 # Local Scope
print(x)
my_func() # Output: 10
If you try to access the variable outside of the function, Python raises an error.
def my_func():
x = 10 # Local Scope
print(x)
my_func() # Output: 10
# Attempting to access x outside of function
print(x) # NameError: name 'x' is not defined
Enclosing Scope
This scope applies to nested functions. When a function is defined inside another function, the inner function can access variables in the outer (enclosing) function.
For example:
def outer_func():
x = "outer" # Enclosing scope
def inner_func():
# Python first looks for x in in the local scope, doesn't find it,
# then searches the enclosing scope
print(x)
inner_func()
outer_func() # Output: outer
In this example, the function outer_func() is defined. Inside this function, a variable x is created and assigned the value "outer". Then, another function inner_func() is defined inside outer_func().
The inner_func() function contains a print(x) statement. After defining inner_func(), outer_func() calls it.
When outer_func() is called, it creates the variable x and the calls inner_func(). While executing inner_func(), Python encounters print(x) statement and looks for the variable x. Python first checks the local scope of inner_func(), doesn’t find it, and then checks the enclosing scope of outer_func(), where x is found.
As a result, the value "outer" is printed.
Local Variable in Inner Function
When the inner function defines a variable with the same name as in the enclosing function, it overrides the outer variable within its own scope.
For example:
def outer_func():
x = "outer" # Enclosing scope variable
def inner_func():
x = "inner" # Local variable to inner_func (shadows outer x)
print(x) # Prints the local variable 'x' of inner_func
inner_func() # Calls inner_func
print(x) # Still uses outer_func's x (unchanged)
outer_func() # Calls outer_func
Output:
inner
outer
In this example, outer_func() defines a variable x with the value "outer".
Inside inner_func(), a new variable x is assigned the value "inner". This local variable shadows the x defined in outer_func() within its own scope but doesn’t replace or modify it.
As a result, when print(x) is executed inside inner_func(), Python uses the inner variable, and the output is "inner".
After calling inner_func(), I have printed x to show that its value in the enclosing scope of outer_func() is still "outer".
The nonlocal Keyword
The nonlocal keyword allows you to modify the variable in the enclosing scope (the outer function). Without nonlocal keyword, any assignment in the inner function would create a new local variable, leaving the outer variable unchanged.
For example:
def outer_func():
x = "outer" # Enclosing scope variable
def inner_func():
nonlocal x # Tells Python to use x from the outer_func
x = "inner" # Modify the outer variable x
print(x) # Prints the modified value of x
inner_func() # Calls inner_func
print(x) # Print x again to show that it was changed by inner_func
outer_func() # Calls outer_func
Ouput:
inner
inner
In this example, outer_func() defines a variable x with the value "outer".
Inside inner_func(), the statement nonlocal x tells Python to use the variable x from the enclosing scope (outer_func), instead of creating a new local variable. Then x is assigned the value "inner", which modifies the x in outer_func‘s scope.
When print(x) is executed inside inner_func(), it prints "inner".
After calling inner_func(), printing x in outer_func() also prints "inner", showing that the value of x in the enclosing scope was changed by inner_func().
Global Scope
Variables defined at the top level of a script or module are considered global and can be accessed from anywhere within the code, including inside functions.
For example:
x = "global" # Global scope
def my_func():
print(x) # Accessible here
my_func()
print(x) # Also accessible here
Output:
global
global
Local Variable in Function
When a function defines a variable with the same name as a global variable, it shadows the global variable within the function’s local scope, without changing the global variable itself.
For example:
x = "global" # Global variable
def my_func():
x = "local" # Local variable
print(x) # Prints the local variable
my_func() # Calls the function my_func
print(x) # Prints the global varaible
Output:
local
global
In this example, a variable x is defined at the global level with the value "global".
Inside my_func(), a new variable x is assigned the value "local". This variable is local to the function and shadows the global x within the function’s scope, but it does not change the global variable.
As a result, when print(x) is executed inside my_func(), Python uses the local variable, and the output is "local".
After calling my_func(), print(x) is executed outside the function. Since this is the global scope, Python refers to the global variable, and its value remains "global".
The global Keyword
The global keyword allows you to modify a variable defined in the global scope from within a function. Without the global keyword, any assignment to a variable inside the function would create a new local variable, leaving the global variable unchanged.
For example:
x = "global" # Global variable
def my_func():
global x # Refers to the global variable x
x = "local" # Modifies the global varaible
print(x) # Prints the modified global variable
my_func() # Calls the function my_func
print(x) # Prints the modified global variable
In this example, a global variable x is defined with the value "global".
Inside my_func(), the statement global x allows the function to access and modify the global variable instead of creating a local one. The assignment x="local" changes the value of global variable.
When print(x) is executed inside the function, it prints "local" and printing x outside the function also prints "local", confirming that the global variable was modified by the function.
Built-in Scope
The built-in scope contains Python’s predefined names, such as built-in functions, data types, and constants, which are available throughout the program without requiring any imports.
For example:
x = 15 # int -> built-in data type
print(len("hello")) # print() and len() -> built-in functions
print(True) # True -> built-in variable (constant)