Skip to main content

Local and Global Scope

Parameters and variables that are assigned in a called function are said to exist in that function’s local scope. Variables that are assigned outside all functions are said to exist in the global scope. A variable that exists in a local scope is called a local variable, while a variable that exists in the global scope is called a global variable. A variable must be one or the other; it cannot be both local and global.

Think of a scope as a container for variables. When a scope is destroyed, all the values stored in the scope’s variables are forgotten. There is only one global scope, and it is created when your program begins. When your program terminates, the global scope is destroyed, and all its variables are forgotten. Otherwise, the next time you ran a program, the variables would remember their values from the last time you ran it.

A local scope is created whenever a function is called. Any variables assigned in the function exist within the function’s local scope. When the function returns, the local scope is destroyed, and these variables are forgotten. The next time you call the function, the local variables will not remember the values stored in them from the last time the function was called. Local variables are also stored in frame objects on the call stack.

Scopes matter for several reasons:

  • Code in the global scope, outside of all functions, cannot use any local variables.
  • However, code in a local scope can access global variables.
  • Code in a function’s local scope cannot use variables in any other local scope.
  • You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named spam and a global variable also named spam.

The reason Python has different scopes instead of just making everything a global variable is so that when variables are modified by the code in a particular call to a function, the function interacts with the rest of the program only through its parameters and the return value. This narrows down the number of lines of code that may be causing a bug. If your program contained nothing but global variables and had a bug because of a variable being set to a bad value, then it would be hard to track down where this bad value was set. It could have been set from anywhere in the program, and your program could be hundreds or thousands of lines long! But if the bug is caused by a local variable with a bad value, you know that only the code in that one function could have set it incorrectly.

While using global variables in small programs is fine, it is a bad habit to rely on global variables as your programs get larger and larger.

Local Variables Cannot Be Used in the Global Scope

Consider this program, which will cause an error when you run it:

def spam():
eggs = 31337
spam()
print(eggs)

If you run this program, the output will look like this:If you run this program, the output will look like this:

Traceback (most recent call last):
File "C:/test1.py", line 4, in <module>
print(eggs)
NameError: name 'eggs' is not defined

The error happens because the eggs variable exists only in the local scope created when spam() is called. Once the program execution returns from spam, that local scope is destroyed, and there is no longer a variable named eggs. So when your program tries to run print(eggs), Python gives you an error saying that eggs is not defined. This makes sense if you think about it; when the program execution is in the global scope, no local scopes exist, so there can’t be any local variables. This is why only global variables can be used in the global scope.

Local Scopes Cannot Use Variables in Other Local Scopes

A new local scope is created whenever a function is called, including when a function is called from another function. Consider this program:

def spam():
eggs = 99
bacon()
print(eggs)

def bacon():
ham = 101
eggs = 0

spam()

When the program starts, the spam() function is called, and a local scope is created. The local variable eggs is set to 99. Then the bacon() function is called, and a second local scope is created. Multiple local scopes can exist at the same time. In this new local scope, the local variable ham is set to 101, and a local variable eggs — which is different from the one in spam()’s local scope — is also created and set to 0.

When bacon() returns, the local scope for that call is destroyed, including its eggs variable. The program execution continues in the spam() function to print the value of eggs. Since the local scope for the call to spam() still exists, the only eggs variable is the spam() function’s eggs variable, which was set to 99. This is what the program prints.

The upshot is that local variables in one function are completely separate from the local variables in another function.

Global Variables Can Be Read from a Local Scope

Consider the following program:

def spam():
print(eggs)
eggs = 42
spam()
print(eggs)

Since there is no parameter named eggs or any code that assigns eggs a value in the spam() function, when eggs is used in spam(), Python considers it a reference to the global variable eggs. This is why 42 is printed when the previous program is run.

Local and Global Variables with the Same Name

Technically, it’s perfectly acceptable to use the same variable name for a global variable and local variables in different scopes in Python. But, to simplify your life, avoid doing this. For example, consider the following program:

def spam():
eggs = 'spam local'
print(eggs) # prints 'spam local'

def bacon():
eggs = 'bacon local'
print(eggs) # prints 'bacon local'
spam()
print(eggs) # prints 'bacon local'

eggs = 'global'
bacon()
print(eggs) # prints 'global'

When you run this program, it outputs the following:

bacon local
spam local
bacon local
global

There are actually three different variables in this program, but confusingly they are all named eggs. The variables are as follows:

  • A variable named eggs that exists in a local scope when spam() is called.

  • A variable named eggs that exists in a local scope when bacon() is called.

  • A variable named eggs that exists in the global scope.

Since these three separate variables all have the same name, it can be confusing to keep track of which one is being used at any given time. This is why you should avoid using the same variable name in different scopes.

The global Statement

If you need to modify a global variable from within a function, use the global statement. If you have a line such as global eggs at the top of a function, it tells Python, “In this function, eggs refers to the global variable, so don’t create a local variable with this name.” For example, consider the following program:

def spam():
global eggs
eggs = 'spam'

eggs = 'global'
spam()
print(eggs)

When you run this program, the final print() call will output this:

spam

Because eggs is declared global at the top of spam(), when eggs is set to 'spam', this assignment is done to the globally scoped eggs. No local eggs variable is created.

There are four rules to tell whether a variable is in a local scope or global scope:

  • If a variable is being used in the global scope (that is, outside of all functions), then it is always a global variable.
  • If there is a global statement for that variable in a function, it is a global variable.
  • Otherwise, if the variable is used in an assignment statement in the function, it is a local variable.
  • But if the variable is not used in an assignment statement, it is a global variable.

To get a better feel for these rules, here’s an example program.

def spam():
global eggs
eggs = 'spam' # this is the global

def bacon():
eggs = 'bacon' # this is a local

def ham():
print(eggs) # this is the global

eggs = 42 # this is the global
spam()
print(eggs)

In the spam() function, eggs is the global eggs variable because there’s a global statement for eggs at the beginning of the function. In bacon(), eggs is a local variable because there’s an assignment statement for it in that function. In ham(), eggs is the global variable because there is no assignment statement or global statement for it in that function. Running the program will output the following:

spam

Note: If you ever want to modify the value stored in a global variable from in a function, you must use a global statement on that variable.

If you try to use a local variable in a function before you assign a value to it, as in the following program, Python will give you an error.

def spam():
print(eggs) # ERROR!
eggs = 'spam local'

eggs = 'global'
spam()

If you run the previous program, it produces an error message.

Traceback (most recent call last):
File "C:/sameNameError.py", line 6, in <module>
spam()
File "C:/sameNameError.py", line 2, in spam
print(eggs) # ERROR!
UnboundLocalError: local variable 'eggs' referenced before assignment

This error happens because Python sees that there is an assignment statement for eggs in the spam() function and, therefore, considers eggs to be local. But because print(eggs) is executed before eggs is assigned anything, the local variable eggs doesn’t exist. Python will not fall back to using the global eggs variable.

Functions as "Black Boxes"

Often, all you need to know about a function are its inputs (the parameters) and output value; you don’t always have to burden yourself with how the function’s code actually works. When you think about functions in this high-level way, it’s common to say that you’re treating a function as a “black box.”

This idea is fundamental to modern programming. We will explore functions that were written by other people later in the course. While you can take a peek at the source code if you’re curious, you don’t need to know how these functions work in order to use them. And because writing functions without global variables is encouraged, you usually don’t have to worry about the function’s code interacting with the rest of your program.