AlgoMaster Logo

Scope & Namespace

Last Updated: January 3, 2026

6 min read

Understanding scope and namespace in Python is crucial for writing clean, efficient, and bug-free code.

They dictate how variables are accessed and where they exist in your code. It can feel a bit like navigating a maze at first, but with the right map (filled with examples and insights) you'll find your way around easily.

Let’s dive in!

What is Scope?

Scope refers to the context in which a variable is defined and can be accessed. In Python, there are several types of scope that define where a variable is valid, including:

  • Local Scope: This is the scope within a function. Variables defined inside a function can only be accessed within that function.
  • Enclosing Scope: This is relevant in nested functions. If you have a function defined within another function, the inner function can access variables from the outer function.
  • Global Scope: Variables defined at the top level of a script or module are accessible throughout the module.
  • Built-in Scope: This includes names that are pre-defined in Python, like print(), len(), and others.

Here’s a simple example to illustrate local and global scopes:

In this code, x is defined globally, making it accessible inside my_function(). However, y is local to my_function() and will raise a NameError if you try to access it outside the function.

Understanding Namespaces

A namespace is a container that holds a set of identifiers (variable names) and their corresponding objects. In Python, namespaces allow you to avoid naming conflicts in your code. There are four main types of namespaces:

  1. Built-in Namespace: Contains names such as keywords and built-in functions.
  2. Global Namespace: This is created when the main program runs and contains names defined at the top level of the module.
  3. Local Namespace: This is created when a function is called and includes names defined within that function.
  4. Enclosing Namespace: Exists in nested functions, holding names from the enclosing function’s local scope.

Let’s see how these namespaces interact. Consider this code:

Here, inner_function() can access outer_var from the enclosing scope, but trying to access inner_var from outer_function() results in an error. This showcases how scopes and namespaces work together to manage variable visibility.

Variable Resolution Order: LEGB Rule

Python follows a specific order to resolve variable names, known as the LEGB rule:

  • Local: Names assigned within a function.
  • Enclosing: Names in the scope of enclosing functions.
  • Global: Names assigned at the top level of a module.
  • Built-in: Names pre-defined in Python.

This order is crucial for understanding which variable will be used when there are conflicting names. Here’s a practical example:

In this example, each level of scope has its own x, and the output will be:

This demonstrates how Python resolves names based on the LEGB rule, providing you with a clear understanding of which variable is being referenced at any point.

Modifying Global and Local Variables

When you want to modify a global variable inside a function, you have to declare it as global. Otherwise, Python will treat it as a local variable. Here’s how it works:

By using the global keyword, we tell Python to use the global count variable instead of creating a new local one. This is particularly useful for maintaining state across function calls.

Now, let’s consider a scenario where you might misuse the global keyword:

Here, value is treated as a local variable because it’s being assigned in the function, but without the global declaration, Python raises an error because it cannot find a local variable named value before it’s referenced.

Enclosing Scope and Closures

When dealing with nested functions, you may have scenarios where you need to capture a variable from an enclosing scope, which leads us to closures. A closure remembers the environment in which it was created, allowing it to access variables from the enclosing scope even after that scope has finished executing.

Here's a simple example:

In this case, inner_function is a closure that captures the msg variable from outer_function. Even after outer_function has finished executing, greet still remembers msg.

Closures are particularly useful for creating function factories, where you need to generate functions with specific behavior based on the outer function’s input.

Now that you understand scope and namespace, you are ready to explore global and nonlocal variables.

In the next chapter, we will look at how these keywords can help you manage state across different scopes and improve your function design.