
Variable Scope
Variables are only available in the area where they are defined. This area is called the scope of the variable. Depending on how and where a variable is defined, it may or may not be accessible in certain parts of your code. Here, you will discuss what variables in Python represent, the difference in defining them inside or outside a function, and how the global and nonlocal keywords can be used to override these default behaviors.
Variables
A variable is a mapping between a name and an object at a certain location in the computer's memory. For example, if you set x = 5, then x is the variable's name, and the value 5 is stored in memory. Python keeps track of the mapping between the name x and the location of the value using namespaces. Namespaces can be thought of as dictionaries, with the names as the keys of the dictionary, and locations in memory as the values.
Note that when a variable is assigned to the value of another variable, this just means they are pointing to the same value, not that their equality will be maintained when one of the variables is updated:
x = 2
y = x
x = 4
print("x = " + str(x))
You should get the following output:
x = 4
print("y = " + str(y))
You should get the following output:
y = 2
In this example, both x and y are initially set to point to integer 2. Note that the line y = x here is equivalent to writing y = 2. When x is updated, it is updated to bind to a different location in memory, and y remains bound to the integer 2.
Defining inside versus outside a Function
When you define a variable at the start of a script, it will be a global variable, accessible from anywhere in the script. This includes within the functions themselves:
x = 5
def do_things():
print(x)
do_things()
With this code, you should get the following output:
5
However, if you define a variable within a function, it is only accessible within that function:
def my_func():
y = 5
return 2
my_func()
You should get the following output:
2
Now, enter the value y and observe the output
y
You should get the following output:

Figure 3.30: We are unable to access the local variable y
Note that if you define a variable within a function that has already been defined globally, the value will change depending on where the variable is accessed. In the following example, x is defined globally as 3. However, it is defined within the function as 5, and when accessed within the function, you can see it takes the value of 5.
x = 3
def my_func():
x = 5
print(x)
my_func()
You should get the following output:
5
However, when it is accessed outside of the function, it takes the global value, 3.
This means you need to take care when updating global variables. For instance, can you see why the following fails to work? Take a look:
score = 0
def update_score(new_score):
score = new_score
update_score(100)
print(score)
You should get the following output:
0
Within the function, the score variable is indeed updated to be equal to 100. However, this variable is only local to the function, and outside the function the global score variable is still equal to 0. However, you can get around this with the global keyword.
The Global Keyword
The global keyword simply tells Python to use the existing globally defined variable, where the default behavior will be to define it locally. You can do this using the same example as before:
score = 0
def update_score(new_score):
global score
score = new_score
print(score)
You should get the following output:
0
Now, you update the score to 100 as shown in the following code snippet:
update_score(100)
Now, to print the scores
print(score)
You should get the following output:
100
The Nonlocal Keyword
The nonlocal keyword behaves in a similar way to the global keyword, in that it does not define the variable locally, and instead picks up the existing variable definition. However, it doesn't go straight to the global definition. It first looks at the closest enclosing scope; that is, it will look "one level up" in the code.
For example, consider the following:
x = 4
def myfunc():
x = 3
def inner():
nonlocal x
print(x)
inner()
myfunc()
You should get the following output:
3
In this example, the inner function takes the variable definition's x from myfunc, and not the global keyword's x. If you instead write global x, then the integer 4 will be printed.