Skip to main content

Variable Scope Understanding in Python

Variable Scope Understanding in Python | Rustcode

Variable Scope Understanding in Python

Knowing variable scope in Python is essential for writing clear, bug-free code. Scope tells you where a variable can be accessed or modified. Python uses the formal LEGB rule—Local, Enclosing, Global, Built-in—to resolve variable names. Understanding these rules helps you avoid name clash errors, accidental overwrites, and surprises in your code’s behavior.


Why Learn Variable Scope?

  • Avoid Bugs: Prevent unexpected behavior by knowing which variable is being accessed.
  • Encapsulation: Keep variables private to functions or classes, reducing conflicts.
  • Debugging: Quickly diagnose "NameError" and similar bugs.

The LEGB Rule Explained

The LEGB rule is Python’s strategy for resolving variable names. When you use a variable, Python looks for it in this order:

  • Local: names assigned inside a function (including function arguments)
  • Enclosing: names in enclosing (outer) functions in nested functions
  • Global: names assigned at the top-level of a module or script
  • Built-in: names preassigned in Python (e.g., len, print)

If Python finds the name at any step, it stops searching and uses that variable.


Types of Scope in Python

  • Local — inside a function or method
  • Enclosing — in any and all enclosing functions
  • Global — at the top-level of a module or declared with global
  • Built-in — always available from Python itself

Local Scope

A variable assigned inside a function is local to that function and exists only there.

def greet():
    message = 'Hello'
    print(message)    # Accessible here

greet()
print(message)        # Error: message is not defined
Note: Local variables cannot be used outside their function.

Enclosing (Nonlocal) Scope

In nested functions, the outer (enclosing) function’s variables can be accessed by inner functions but are not global.

def outer():
    outer_var = 'I am from outer'

    def inner():
        print(outer_var)  # Finds in enclosing scope

    inner()
outer()

Output:

I am from outer
Explanation:
  • Inner functions look outside their definition for variables if not local.
  • Use nonlocal to modify variables in the enclosing scope (Python 3+).

Global Scope

A variable defined at the top-level (not in any function/class) is global and can be accessed anywhere in the module.

x = 'I am global'

def foo():
    print(x)  # Reads global x

foo()
print(x)

Output:

I am global
I am global
Modifying Globals:
  • To update a global variable inside a function, use global x.
count = 0
def increment():
    global count
    count += 1

Built-in Scope

The broadest scope. Includes Python’s built-in functions, exceptions, and constants such as len, print, SyntaxError.

print(len("hello"))  # Both are built-in names

Quick Reference Table: LEGB Scopes

Scope Where Defined Accessible in... Modifiable?
Local Inside function/method That function only Yes (in function)
Enclosing Outer functions in nested functions Inner (nested) functions Yes (with nonlocal)
Global Top-level of the module; declared with global Entire module Yes (with global)
Built-in Python itself Everywhere No

Important-Points

  • Keep most variables in local scope—minimizes bugs and makes debugging easier.
  • Only use global or nonlocal when necessary.
  • Remember: variables inside and outside functions with the same name are different by default.
  • Accessing a variable before assignment (when shadowed) causes UnboundLocalError.
x = 10
def print_x():
    print(x) # refers to global x

def shadowed():
    x = 20
    print(x) # refers to local x

print_x()   # 10
shadowed()  # 20
print(x)    # 10

Conclusion

Mastering scope in Python—especially the LEGB rule—helps you write safer, more predictable programs. Keep variable lifetimes as short as possible by preferring local variables. Refer back to this guide whenever you’re unsure which variable Python is using!

Comments