Variable Scope and Namespace in Python
Learn the various scopes of variables in Python like local, global and non local and their usage with examples.

Topics Covered
- An Experiment with Names
- Python Namespace
- Global vs Local vs Nonlocal Scope
- global statement
- Nonlocal scope
- Built-in Functions - globals() and locals()
- Problems to solve
An Experiment with Names
People not only have official names, but they also have nicknames used by their parents, friends, and close acquaintances.
Let’s try to understand how Python interprets names through variables.
Code
name = "Pylenin"
print(name)
Output
Pylenin
Let’s now write a function that contains the name that I am called at home.
Code
name = "Pylenin"
def home():
name = "Lenin"
print(name)
home()
Output
Lenin
When we call the home
function, Python prints Lenin
.
What would happen, if I also print the name
variable outside the function?
Code
name = "Pylenin"
def home():
name = "Lenin"
print(name)
home()
print(name)
Output
Lenin
Pylenin
Although the name
variable inside the function refers to Lenin
, when you print the name
variable outside the function, it refers to the variable declared outside the function.
The above example demonstrates the working of Global and Local Scope.
Before we understand that, let’s understand Namespace in Python.
Python Namespace
Namespace in Python is a collection of names.
When you declare a variable or an object(everything in Python is an object), Python looks up the name in what is known as a Namespace - a place where names live. If it doesn’t exist, Python creates the name. The location of a name’s assignment in your code determines the scope of the name’s visibility to your code.
For example, when you assign name = "Pylenin"
, Pylenin
is an object which is stored in memory and name
is the name we associate it with. We can get the address of an object through the built-in function id()
.
Code
name = "Pylenin"
print(id(name))
Output
2088455986800
Now unlike other languages like C, C++ etc., you don’t have to declare a variable way ahead of time. Also, you can assign any value to a variable as many times you want during the course of a program. Everytime this happens, the id()
of the object changes.
Code
name = "Pylenin"
print(id(name))
name = "Lenin"
print(id(name))
name = [1, 2, 3, 4]
print(id(name))
Output
1874212773488
1874212702448
1874212772928
Python uses the assignment location of a variable/name to bind it to a particular namespace. In other words, the place where you assign a name in your source code determines the namespace it will live in, and hence its scope of visibility.
Global vs Local vs Nonlocal Scope
- If a variable is assigned inside a
def
, it is local to that function. - If a variable is assigned in an enclosing
def
, it is nonlocal to nested functions. - If a variable is assigned outside all defs, it is global to the entire file.
Code
# global scope
name = "Pylenin"
def home():
# local scope
name = "Lenin"
def sister():
# nonlocal scope
name = "Brother"
print("The value of name in sister function is", name)
sister()
print("The value of name in home function is", name)
home()
print("The value of name outside a function is", name)
Output
The value of name in sister function is Brother
The value of name in home function is Lenin
The value of name outside a function is Pylenin
If you reuse a global name inside a local namespace, then Python creates a new local variable with the same name.
global statement
If you don’t want to create a new local variable inside your function, you can use the global
keyword.
Code
name = "Pylenin"
def home():
global name
print(name)
home()
Output
Pylenin
By adding a global
declaration to the above example, the variable name
inside the def refers to the variable name
outside the function. They are the same variable this time.
Nonlocal scope
It restricts scope lookup to just enclosing defs and not in the global scope. Nonlocal scope can only be applied for nested functions.
Code
name = "Pylenin"
def home():
name = "Lenin"
def sister():
nonlocal name
name = "Brother"
print("The value of name in sister function is", name)
sister()
print("The value of name in home function is", name)
home()
print("The value of name outside a function is", name)
Output
The value of name in sister function is Brother
The value of name in home function is Brother
The value of name outside a function is Pylenin
As you can see from the above example, by usig the nonlocal
keyword inside the sister
function, you can access the variable name
created in the enclosed scope of the home
function.
Built-in Functions - globals() and locals()
To check if a variable is in the global or local scope, you can make use of globals()
and locals()
built-in methods.
Python maintains data about each identifier appearing in your program. This data relates to the type, value, scope level and location of an identifier (also called symbol). By using the globals()
and locals()
methods, you get to access all that data in the form of a dictionary.
Code
name = "Pylenin"
def home():
name = "Lenin"
def sister():
name = "Brother"
print(globals()["name"])
print(locals()["name"])
Output
Pylenin
Pylenin
Now you might be confused looking at the results. Since in the global scope, our variable name
corresponds to the value Pylenin
, it makes sense that globals()
built-in function contains that value in the name
key.
However, it is also returning the same value for locals()
built-in function. Why is that?
The reason is, Python is unable to distinguish between global scope and local scope when you are accessing the locals()
function in the global scope.
Let’s try to move it within a function.
Code
name = "Pylenin"
def home():
name = "Lenin"
def sister():
name = "Brother"
print("locals() within sister returns",locals()["name"])
print("locals() within sister returns",locals()["name"])
sister()
home()
print(globals()["name"])
Output
locals() within sister returns Lenin
locals() within sister returns Brother
Pylenin
As you can see, now the locals()
function is returning the appropriate name in the local scope of each function.
Problems
-
What is the output of the following code and why?
X = 'Spam' def func(): X = 'NI!' func() print(X)
-
What is the output of the following code and why?
X = 'Spam' def func(): global X X = 'NI!' func() print(X)