4) Functions and Scope Lesson

Python Variable Scope

12 min to complete · By Martin Breuss

In this lesson, you'll dive deeper into the concept of scopes in programming, and you'll walk through an example step-by-step.

How does Wikipedia define scope:

In computer programming, the scope of a name binding – an association of a name to an entity, such as a variable – is the region of a computer program where the binding is valid: where the name can be used to refer to the entity. Such a region is referred to as a scope block. In other parts of the program, the name may refer to a different entity (it may have a different binding), or to nothing at all (it may be unbound).

Ufff! That's a heavy definition and doesn't seem that straightforward. Let's take another approach and try this again from the beginning.

Thinking About Variable Scope

Start by thinking of a box:

Cardboard box - Photo by https://unsplash.com/@umbra_media Christopher Bill on Unsplash

_Photo by Christopher Bill https://unsplash.com/@umbra_media _

Now think of another box inside that box:

Sweets in a box - Photo by https://unsplash.com/@tvick Taylor Vick on Unsplash

Photo by Taylor Vick https://unsplash.com/@tvick

Wait, no! Keep your imagination in check! There should be another box inside the box. Okay, okay, that's the inner box. So you're now picturing a cardboard box with another box inside that has some candy in it. Fine, that'll do.

These boxes are similar to how scopes work. You can fill different scopes with different variables. So you can have something called a candy inside the outer box, and you can have something else that is also called candy in the inner box. Even though they have the same name, they will be two different candies.

Just like in the example in the previous lesson, you won't be able to access the candy in the inner box from the outer box. No matter how hard you try:

Dog in a box - Photo by https://unsplash.com/@erdaest Erda Estremera on Unsplash

Photo by Erda Estremera https://unsplash.com/@erdaest

That covers the very basics of scopes, but the metaphor doesn't entirely hold up. It might be counterintuitive to know that you can access things inside the outer box from the one that's nested inside of it. So scopes aren't just ordinary boxes, and you'll now learn about two different types of scopes:

  1. Global scope
  2. Local scope

Most of the time up to now, you've worked in the global scope of your script. In the previous lesson, you opened a local function scope and defined variables that existed only in there.

Global Scope

Each Python session that you start, for example, by running a script or an interpreter session, has a global scope.

Any variable that you define in the global scope is accessible within any of the inner scopes you might create in that session. That's where the box metaphor stops making a whole lot of sense.

Even a function within a function within a function (etc.) can still use a variable that has been defined in the global scope without needing to pass it as an argument. Nested scopes have access to anything defined in their outer scopes:

name = "Mycroft"

def print_name_box():
    print(name)

    def smaller_box():
        print(name)

        def smallest_box():
            print(name)

        smallest_box()

    smaller_box()

print_name_box()

Run this example code in a script on your own computer or in an online playground. As you can see, the name variable is accessible in any of the nested function scopes, even though you only defined it once in the global scope of your script.

However, this is a one-way street and doesn't work the other way around, as you've seen in the previous lesson.

In the following graphic, you'll see a visualization of the different scopes within this code snippet. Each new scope is surrounded by a colored square. Even though you're opening up some new scopes, the value for name stays accessible as "Mycroft" in all scopes. This is indicated in the graphic with the red background behind all scopes:

A graphic showing scopes in Python

As you can see, variables defined in the global scope are accessible in all inner nested scopes of your script unless they get overwritten.

Local Scope

Variables that are defined within a local scope are available in that local scope, and any scopes nested within it. A global variable will only exist within a local scope if there's no variable with the same name in the local scope. If a local variable has the same name as a global variable, the local variable will always take precedence.

To exemplify this, you'll take another look at your previous example with the name variable:

name = "Mycroft"

def print_name_box():
    print(name)

    def smaller_box():
        # (Re)assigning a variable within a local scope
        # overwrites the same variable from an outer scope
        # You also can't use the global variable *before*
        # assigning it, if you assign it anywhere in that scope.

        # --TASK--: uncomment the print() function below
        #     and interpret the results when running the script

        # print(name)
        name = "Sherlock"

        def smallest_box():
            # Inner scopes always draw from the next outer layer.
            # After `name` got overwritten, the name that will
            # be printed is NOT the global-scope name anymore
            print(name)

        smallest_box()

    smaller_box()

print_name_box()

Copy this code into your local IDE and run it to see the output, or use this online playground. Just like in the previous example, you can see that the value of name cascades down into the inner scopes.

In the scope of smaller_box(), the name variable gets assigned a new value, "Sherlock". It keeps that new value further in any deeper-down inner scopes:

A graphic showing scopes in Python

In the graphic above, you can again see all new scopes surrounded by a colored box. The name variable has the value "Mycroft" in all scopes that have a red background, and it has the value "Sherlock" in all scopes that have a blue background.

Practicing Scope

  • Run both examples in your interpreter.
  • Uncomment the call to print() in the second example and think about what is happening there.

By now, you've encountered a lot of different programming concepts, and this can get overwhelming. In the next lesson, you'll get to know the basic structure of a Python script that you should aim to stick to when writing your programs.

Summary: What is Variable Scope

  • There are two different scopes that you need to concern yourself with:
    1. Global scope
    2. Local scope
  • You can have nested local scopes. A variable defined in an outer scope will be available in any inner scope unless the variable is defined again. The most specific variable takes precedence.