1. python
  2. /basics
  3. /scope

Understanding Scope in Python

Getting Started

Have you ever wondered how Python keeps track of all the variables we create in our code? The answer lies in scope and namespaces.

In Python, a namespace is a container that maps names to objects. They exist to avoid naming conflicts between variables with the same name in different parts of the code.

Scope, on the other hand, defines the context in which a variable exists and how it's being accessed. It determines the hierarchical order in which namespaces are searched to find the correct mapping of a name to an object. In other words, scope determines the accessibility and lifetime of a variable.

Local Scope

When we define a variable within a function, it has local scope. In turn, that variable can only be accessed and used inside the function. If we try to access it from the outside, we'll get an error as a result.

Consider the following example:

def greeting():
    name = "Guido van Rossum"
    print(f"Hello, {name}!")

greeting() # Output: Hello, Guido van Rossum!
print(name) # Output: NameError: name 'name' is not defined

As we can see our variable is defined inside the greeting function and has local scope. When we call the function, it prints a greeting message with the name. However, when we try to access the variable outside the function, we get an error, because the variable only exists within the local scope of the greeting function.

Enclosing Scope

There are certainly cases where we'll need to nest functions. Scope-wise, the inner function can access variables defined in an outer one. So, this is exactly what we mean when we say that they have enclosing scope.

Let's modify the previous example and demonstrate the claim:

def outer_function():
    name = "Guido van Rossum"
    
    def inner_function():
        print(f"Hello, {name}!")
    
    inner_function()

outer_function() # Output: Hello, "Guido van Rossum"!

Upon calling the outer function, it will point to the inner one nested inside and print out the greeting message defined in the name variable.

Global Scope

Variables defined at the top level of our Python scripts, outside of any functions, have global scope and can be accessed and used from anywhere in your code.

However, while global variables can be accessed from anywhere, it's generally considered better practice to avoid using them, as we can reduce the risk of naming conflicts and make the code easier to debug.

temperature = 68

def convert_to_celsius():
    celsius = round((temperature - 32) * 5/9)
    print("The temperature in Celsius is", celsius)

convert_to_celsius() # Output: The temperature in Celsius is 20

To illustrate this we used an example where the temperature variable is defined at the top level of the script and has global scope. Logically, it can be accessed and used from within the convert_to_celsius function, which converts the temperature from Fahrenheit to Celsius. When we call the function, it prints the converted temperature in Celsius.

Built-in Scope

In addition to the scope we covered so far, Python also has a built-in scope, containing a set of reserved names that have special meanings in Python. We already saw common functions and types such as print, len, range, str, int, and float, to name a few.

In general, we should stick to descriptive and meaningful names for our variables and functions. By doing so, we can improve readability and maintainability while reducing the risks of potential conflicts.

Feel free to learn more about the built-in scope and reserved naming, as well as a peek into the basics of variables.

Additional Resources

Official Documentation for Built-in Objects

Python Scope and Namespaces

The Basics of Variables in Python