• Python
Python Fundamentals
  • Python Variables
  • Python Operators
  • Python Input-Output
  • Python Type Conversion
Python Data Types
  • Python Strings
  • Python List
  • Python Tuple
  • Python Dictionnaries
  • Python Sets
Python Flow Control
  • Python Conditions
  • Python For Loop
  • Python While Loop
  • Python Break and Continue
Python Functions
  • Python Functions
  • Python Arguments
  • Python Functions Scope
  • Python Recursion
Python Classes
  • Python Classes
  • Python Classes and Static Methods
  • Python Properties
  • Python Decorators
  • Python Error Handling

Create an Account

FREE

Join our community to access more courses.

Create Account
  • Pricing
  • Blog

On this page

Where Variables Live: Understanding ScopeWhat is Variable Scope?Local ScopeGlobal ScopeThe global KeywordEnclosing (Nonlocal) ScopeThe nonlocal KeywordSummary

Python Functions Scope

Where Variables Live: Understanding Scope

In Python, not all variables are accessible from every part of your program. The scope of a variable determines the region of your code where that variable is recognized and can be used.

Understanding variable scope is fundamental to writing correct, predictable, and bug-free Python code. It helps you manage variable names and prevents unintended interactions between different parts of your program, especially when working with functions.

What is Variable Scope?

Scope refers to the context in which a variable is defined. It defines the variable's lifetime and visibility.

Python follows the LEGB rule to determine the scope of a variable. When you try to access a variable, Python searches for it in this order:

  1. Local (L): Inside the current function or class method.
  2. Enclosing (E): In the scope of any enclosing functions (for nested functions).
  3. Global (G): At the top level of the current module (outside any function or class).
  4. Built-in (B): In the special built-in names provided by Python (like print, len, True, False, None).

If Python doesn't find the variable in any of these scopes, it raises a NameError.

Local Scope

Variables defined inside a function have local scope. They are created when the function is called and cease to exist when the function finishes executing.

You can access a local variable only from within the function where it is defined.

def my_function():
    # 'x' has local scope
    x = 10
    print(f"Inside the function, x is: {x}")

my_function()

# Trying to access x outside the function will cause an error
# print(x) # This line would cause a NameError

Output:

Inside the function, x is: 10
# If you uncomment the last line, you'll get:
# NameError: name 'x' is not defined

The local variable x is only visible and usable within my_function().

Global Scope

Variables defined at the top level of a script, outside of any function or class, have global scope. Global variables can be accessed (read) from anywhere in the script, including inside functions.

# 'y' has global scope
y = 20

def another_function():
    # You can read the global variable y from inside the function
    print(f"Inside the function, y is: {y}")

another_function()
print(f"Outside the function, y is: {y}")

Output:

Inside the function, y is: 20
Outside the function, y is: 20

However, by default, you cannot modify a global variable from inside a function. If you try to assign a value to a variable name that is defined in the global scope, Python creates a new local variable with the same name inside the function instead.

This can lead to confusion or the UnboundLocalError if you try to read the variable before assigning to it within the function:

z = 30 # Global variable

def modify_global_attempt():
    # Python thinks z here is a new local variable.
    # Trying to use it before assigning to it causes an error.
    z = z + 1 # ERROR: UnboundLocalError!
    print(f"Inside function: {z}")

# modify_global_attempt() # This call would cause the UnboundLocalError
print(f"Outside function, z is still: {z}") # z remains 30 globally

The global Keyword

To modify a global variable from inside a function, you must explicitly tell Python your intention using the global keyword before the variable name.

count = 0 # Global variable

def increment_global():
    global count # Declare that we intend to modify the global 'count'
    count = count + 1 # Now this modifies the global variable
    print(f"Inside function, count is: {count}")

print(f"Outside function before call, count is: {count}") # Output: 0
increment_global()
print(f"Outside function after call, count is: {count}")  # Output: 1

Using global should be done cautiously, as it can make code harder to track and debug by allowing functions to have side effects on the global state.

Enclosing (Nonlocal) Scope

Python allows you to define functions inside other functions. These are called nested functions. The inner function has access to variables in its own local scope, the global scope, the built-in scope, and importantly, the scope of the outer (enclosing) function(s).

This intermediate scope is called the enclosing scope.

def outer_function():
    outer_variable = "I'm in the outer scope"

    def inner_function():
        # inner_function can access outer_variable (enclosing scope)
        print(f"Inside inner function: {outer_variable}")

    inner_function() # Call the inner function

outer_function()

# You cannot access outer_variable from outside outer_function
# print(outer_variable) # This would cause a NameError

Output:

Inside inner function: I'm in the outer scope

The inner_function can see outer_variable from its enclosing scope.

Similar to global variables, by default, an inner function cannot modify variables in its enclosing scope. An assignment inside the inner function will create a new local variable there.

The nonlocal Keyword

To modify a variable in the nearest enclosing scope (that is not the global scope) from within a nested function, you use the nonlocal keyword.

def counter():
    count = 0 # Variable in the enclosing scope

    def increment():
        nonlocal count # Declare that we intend to modify the 'count' in the enclosing scope
        count += 1
        print(f"Inner function: count is {count}")

    increment() # Call inner to modify count
    increment() # Call inner again
    print(f"Outer function: final count is {count}")

counter()

Output:

Inner function: count is 1
Inner function: count is 2
Outer function: final count is 2

Without nonlocal, the count += 1 inside increment() would try to create a new local count or cause an UnboundLocalError. nonlocal targets the count variable in counter()'s scope.

Summary

  • Scope determines where variables are accessible.
  • Python follows the LEGB rule to look for names: Local, Enclosing, Global, Built-in.
  • Local variables are defined inside a function and only exist there.
  • Global variables are defined at the top level and can be read from inside functions.
  • Use the global keyword to modify a global variable from inside a function.
  • Enclosing scope refers to variables in an outer function when using nested functions.
  • Use the nonlocal keyword to modify a variable in the nearest enclosing scope.

Understanding scope is crucial for managing variable lifetimes and visibility, preventing naming conflicts, and writing correct and maintainable Python programs.

Continue Learning

Removing Duplicates

Popular

Personalized Recommendations

Log in to get more relevant recommendations based on your reading history.