Mastering Python Scope: A Step-by-Step Guide to the LEGB Rule

By • min read

Introduction

Understanding Python scope is essential for writing clean, predictable code. The LEGB rule—Local, Enclosing, Global, Built-in—defines how Python resolves variable names. This guide will walk you through the hierarchy step by step, show you how to inspect and modify scopes, and help you avoid common pitfalls. By the end, you'll be able to confidently navigate scope boundaries in your Python programs.

Mastering Python Scope: A Step-by-Step Guide to the LEGB Rule
Source: realpython.com

What You Need

Step-by-Step Instructions

Step 1: Grasp the Concept of Scope

Scope determines where a variable name is accessible. Python uses lexical (static) scoping: the scope is determined at compile time based on the structure of the code. Start by creating a simple variable at the top level of a script and try to access it inside a function. Note that variables defined outside functions are global by default.

Step 2: Learn the LEGB Order

When Python looks up a name, it searches in this order:

  1. Local – inside the current function
  2. Enclosing – any and all enclosing functions (from innermost outward)
  3. Global – the top-level scope of the module
  4. Built-in – names in the builtins module (like print, len)

The search stops at the first match. If nothing is found, a NameError is raised.

Step 3: Identify Local Scope

Any variable assigned inside a function (including parameters) exists in that function's local scope. Write a function that defines a variable and returns it. Try accessing the same variable outside the function—it will raise a NameError because it's local.

def my_func():
    x = 10  # local to my_func
    return x

print(x)  # NameError: name 'x' is not defined

Step 4: Understand Enclosing Scope (Nested Functions)

When you have a function inside another function, the inner function can access variables from the enclosing function's scope (but not the other way around). This is the E in LEGB. Create an outer function with a variable, then an inner function that uses that variable. Notice that the inner function can read the variable without any special declaration.

def outer():
    y = 20
    def inner():
        print(y)  # accesses y from enclosing scope
    inner()

outer()  # prints 20

Step 5: Work with Global Scope

Variables defined at the module level are global. They can be read inside functions without any special keyword. But if you try to assign to a global variable inside a function, Python creates a new local variable unless you use the global statement. To modify a global variable from within a function, declare it with global.

z = 100

def modify_global():
    global z
    z = 200

modify_global()
print(z)  # 200, because global was used

Step 6: Explore Built-in Scope

Built-in names are always available. Examples: print, len, range. You can shadow a built-in by naming one of your variables the same, but it's not recommended. To see the built-in scope, you can inspect dir(__builtins__). Never override built-ins unless you have a very good reason.

Step 7: Use the global Statement

The global statement tells Python that a variable name should be treated as referring to the global scope, even if assigned inside a function. Use it sparingly—excessive global variables can make code hard to debug. Only use global when you truly need to modify a module-level variable from within a function.

Mastering Python Scope: A Step-by-Step Guide to the LEGB Rule
Source: realpython.com

Step 8: Use the nonlocal Statement

The nonlocal statement works similarly but for enclosing (non-global) scopes. It allows you to assign to a variable in an enclosing function scope from inside a nested function. Without nonlocal, assignment in the inner function creates a new local variable instead.

def outer():
    a = 1
    def inner():
        nonlocal a
        a = 2
    inner()
    print(a)  # 2, because nonlocal allowed modification

outer()

Step 9: Test Your Knowledge with Examples

Now practice by writing small programs that mix different scopes. Try to predict the output of code snippets. For example:

def func1():
    x = 5
    def func2():
        x = 10
        print(x)
    func2()
    print(x)

func1()  # What will be printed?

Answer: 10 then 5 – because x in func2 is local, not the same as x in func1.

Tips and Common Pitfalls

Remember, mastering scope takes practice. Start with simple examples and gradually introduce nested functions, global modifications, and closures. The LEGB rule is your roadmap—use it to navigate variable resolution with confidence.

Recommended

Discover More

5 Steps to Uncover the Curator and the Next Dark Pictures Teaser in Directive 8020How to Spot the Surveillance Risks in Canada's Bill C-22Breaking the Forking Trap: Meta’s Journey to Continuous WebRTC UpgradesTesla Slashes Model 3 Price in Canada by Importing from China Despite TariffMastering CAN Bus Monitoring with CANopenTerm: A Step-by-Step Guide