Python Introduction

Python Namespace and Scope of a Variable

What is Name in Python?

Have you ever wondered how it would be if the things and people around us had no names? You would have to refer to everything like it, they, etc. Giving names to things or objects around us is how we organise and structure things, and this is also why we use the Python namespace system in Python programming.

Python Namespace

A name (or identifier) is just that, a name we assign to the objects in Python. Every value or element in Python is an object that we can access by using their names.

We use an assignment statement to create a symbolic name that we can use to reference an object. For example, the statement s = ‘luck’ creates a symbolic name s that refers to the string object ‘luck’. In other words, ‘luck’ is the object, and s is the name that is assigned to it. 

The id() Function

If we ever wish to get the address of an object from the RAM, we can use the in-built function id() in Python. So, how do we use it?

                    

p = 'luck
print(id('luck))

print(id(p))

Output:

                    

139894724061232
139894724061232

In the above example, both the statements refer to the same object (‘luck’), so they have the same id. However, this may not happen every time. 

                    

# The id values will be different

p = 9
print('The id is:', id(p))

p = p+2
print('The id is:', id(p))
print('The id is:', id(11))

q = 9
print('The id is:', id(q))
print('The id is:', id(9))

Output:

                    

The id is: 9785152
The id is: 9785216
The id is: 9785216
The id is: 9785152
The id is: 9785152
> 

Wait, how did we get different ids? Let us use a memory diagram to understand this.

 

Python Namespace

Source: Self 

When we started the code, we assigned object 9 to the name p. Then, when we used p = p+2, the name was associated with a new object 11. That is why both id(p) and id(11) have the same value and id.

Then when the program executed q = 9, the previous object 9 got associated with the new name q.

What is a Namespace in Python?

A Python namespace is an efficient system where each and every object in Python has a unique name. Every package, module, class, function and method in Python occupies a namespace in which variable names are set. 

Let us take a real-world example to understand this better. You can compare a namespace to a surname. You may not be able to find only one “Rohit” in a class as there may be many “Rohit”. However, if you try to find “Rohit Sharma” or “Rohit Rao” (with a surname), you will find that there is only one person. 

Similarly, the Python interpreter can understand which exact method or variable you are trying to point to in the code, depending upon the namespace. 

Types of Python Namespace

Python Namespace

Built-in namespace – A Python namespace gets created when we start using the interpreter, and it exists as long as it is in use. When the Python interpreter runs without any user-defined modules, methods, etc., built-in functions like print() and id() are always present and available from any part of a program. These functions exist in the built-in namespace.

Global namespace – A global namespace gets created when you create a module.

Local namespace – This namespace gets created when you create new local functions. 

The built-in namespace encloses the function namespace, which encompasses the local namespace.

Python Variable Scope

A namespace’s lifetime depends on the scope of a variable. If the variable’s scope ends, the lifetime of the Python namespace also comes to an end. That is why we cannot access the objects in the inner namespace from an outer namespace.

Scope refers to the coding region from where we can access a particular object directly (without any prefix). In a program, you will find at least three nested scopes of:

  1. The function that contains the local names.
  2. The module that contains the global names
  3. Scope of the built-in names (outermost).

We cannot access any specific object from anywhere in the code. The access has to be allowed by the scope of the object. When we make a reference inside a function, the interpreter first looks for the name inside the local namespace, then the global namespace and finally the built-in namespace. 

Example of Scope and Namespace in Python

Example 1:

If we create a function within a function, a new scope is enclosed inside the local scope. For example:

                    

def outer_func():
    q = 50
    def inner_func():
        s = 25

p = 100

In the above example, p is a variable in the global namespace, q in the local Python namespace and s in the nested local namespace. 

However, if we are referring from inner_func(), s will be the local variable, q the non-local variable, and p is the global variable. That is why we can assign new values to s, but not to q and p. 

If you try to assign a value to q from inner_func(), a new variable q gets created in the local namespace, and it will be completely different from the non-local q. 

Using a Global Variable

If we use the global variable p, all the reference and assignment will go to p.  

                    

def outer_func():
	p = 50

	def inner_func():
		p = 25
		print ('p -->', p)

	inner_func()
	print('p -->',p)

p = 100
outer_func()
print('p -->',p)

Output:

                    

p --> 25
p --> 50
p --> 100

We got this output because we defined the variable p in three different namespaces and accessed them accordingly. 

Example 2:

                    

def outer_func():
	global p
	p = 50

	def inner_func():
		global p
		p = 25
		print ('p -->', p)

	inner_func()
	print('p -->',p)

p = 100
outer_func()
print('p -->',p)

Output:

                    

p --> 25
p --> 25
p --> 25

In this program, we refer and assign all the values to the global variable p using the global keyword. Hence, we get the same value (that of global p).

Questions and Answers

Q1. What are Python namespaces, why do we use them?

A Python namespace is a collection or a system of names that ensures all the value names in a program are unique, and we can use them without any conflict. We can think of a namespace as a dictionary where the object names are the keys, and their values are the objects. We find each symbolic name in the system with information about the object that the name references.

Q2. How do you create a namespace in Python?

Every package, module, class, function and method occupies a Python namespace in which variable names are set. A namespace gets created automatically when a module or package starts execution. Hence, to create a namespace, all you have to do is call a function/ object or import a module/package. 

For example:

                    

# varA in the global namespace
varA = 25
def A_func():
 
    # varB in the local namespace
    varB = 83
    def B_inner_func():
 
        # varC in the nested local
        # namespace
        varC = 9

Q3. What are namespaces, and how are they used in Python?

Namespaces are collections of different objects that are associated with unique names whose lifespan depends on the scope of a variable. The scope is a region from where we can access a particular object. There are three levels of scopes: built-in (outermost), global, and local. We can only access an object if its scope allows us to do so. 

For example:

                    

# global namespace
var_a = 75
def A_func():
 
    # local namespace
    var_b = 38
    def B_inner_func():
 
        # nested local 
	# namespace
        var_c = 24

We cannot access the variable var_a if we refer to it in the nested local namespace (where var_c is present). If we try to assign a new value to var_a from here, a new variable gets created in the nested local namespace.

Q4. Which is not a valid namespace in Python?

There are mainly three Python namespaces: built-in (outermost), global, and local. A namespace gets created automatically when we execute a module or package. 

Python implements the global and local namespaces as Python dictionaries (not the built-in namespace) and provides built-in functions called globals() and locals() to help us access these namespace dictionaries.

We can use the globals() function to access the objects in the global namespace. 

Example:

                    

>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>}

As you can see, the interpreter already has several entries in globals(). Now, when you define a variable in the global scope:

                    

>>> s = 'Mango'
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 's': 'Mango'}

A new object (‘Mango’) appears in the global namespace dictionary. The dictionary key is the object’s name, s, and the dictionary value is the object’s value, ‘Mango’.

Similarly, the locals() function helps us access objects in the local namespace. 

                    

>>> def l(p, q):
	s = 'Apple'
	print(locals())

>>> f(15, 0.7)
{'s': 'Apple', 'q': 0.7, 'p': 15}

When called within l() function, locals() returns a dictionary that represents the function’s local namespace. Apart from the local variables, locals() also includes the function parameters p and q since they are local to l().

Share with friends

Customize your course in 30 seconds

Which class are you in?
5th
6th
7th
8th
9th
10th
11th
12th
Get ready for all-new Live Classes!
Now learn Live with India's best teachers. Join courses with the best schedule and enjoy fun and interactive classes.
tutor
tutor
Ashhar Firdausi
IIT Roorkee
Biology
tutor
tutor
Dr. Nazma Shaik
VTU
Chemistry
tutor
tutor
Gaurav Tiwari
APJAKTU
Physics
Get Started

Leave a Reply

Your email address will not be published. Required fields are marked *

Download the App

Watch lectures, practise questions and take tests on the go.

Customize your course in 30 seconds

No thanks.