Chapter 6: Function scope

Python scopes

face Josiah Wang

So, what is really happening behind the scenes?

How does Python decide which number variable belongs to which function?

The key is to understand how Python searches for the variable names. It is based on where you define the names. You define variable names in the current scope.

Let’s use the following code as an example.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def make_sound(message):
    noise = "HO?"
    print(f"{message} {noise}")

def repeat_sound(message, times):
    i = 0
    punctuation = "!!"
    while i < times:
        make_sound(message + punctuation)
        i += 1

x = 10
y = 20
repeat_sound("HA", 2)
z = x + y

The global scope

When you first run the program, Python will automatically give you a box labelled global. This box represents the global scope.

Python will put names of any identifiers you have defined so far inside this box. In our example, after executing up to Line 14, the names x, y, make_sound and repeat_sound will be stored inside this box. In case you are wondering, function names are actually variables in Python (remember that we are only defining the function now, and have not yet executed them)!

This list of names in each box is called the namespace.

The global scope

The local scope

Continuing on in Line 14, Python identifies that repeat_sound is a function (by looking inside its box). So before calling repeat_sound("HA", 2), it will first create another new box. This box is called the local scope for repeat_sound. Python also knows that the parent of this box is the global box from earlier (since repeat_sound was defined in the global scope).

Python will then call repeat_sound("HA", 2) and will start inserting any new parameters and variables that is defined from then on inside this new local box.

The local scope of the repeat_sound function call

Another local scope

Finally, Python will reach Line 9. Python cannot find make_sound in its current local box, so it will search for make_sound in the parent box (the global box in this case). It finds it there - perfect! It now creates a new local box for repeat_sound, with the global box as its parent (since that’s where repeat_sound is defined). And we repeat the process of storing variables in this box. If you need to access the message variable, Python will find it in this currently local box and return "HA!!", rather than the "HA" in the make_sound box.

Once a function returns, the current box will be destroyed 💥.

The local scope is now the most recent (undestroyed) box (repeat_sound).

The local scope of the make_sound function call

You can try using this Python visualiser, copy and paste the code, and examine this yourself step by step.