Home
About Us Privacy Policy
 

SCOPES AND LIFETIMES IN PYTHON

ADVERTISEMENT

Advanced Scopes



What is a Scope, and what are its types?

In programming, Scope determines the visibility of an identifier. Let us take a more real-world example to help understand the usage of scopes.

We have all seen movies with government agents with various clearance levels. According to the state government, there are three levels of clearance: confidential, secret, and top-secret. Let us take two government agents named Fox Mulder with a top-secret clearance level and Dana Cox with a confidential clearance level. Fox would be allowed to access all three levels of information, namely, confidential, secret, and top-secret. However, since Dana has a confidential level of access, he won't access secret and top-secret information.

In programming, Scoping works very similarly. It defines the variables that a program can access. There are two levels of scopes:

  • Local Scope
  • Global Scope


ADVERTISEMENT

Local Scope

In Python, Local Scope is an area where an identifier is available within a function. Below is an example :

def foo_fighters():
    no_of_foo_fighters = 1881
    print(f"The no. of foo fighters were {no_of_foo_fighters}.")

# Trying to access the variable from outside of the function
try:
    print(no_of_foo_fighters)
except NameError as e:
    print(e)
finally:
    foo_fighters()

name 'no_of_foo_fighters' is not defined
The no. of foo fighters were 1881.

The above example demonstrates, that the variable "no_of_foo_fighters" is accessible inside of the function foo_fighters(). However, when we attempt to access the variable from outside the function, it is unavailable and thus generates an error. You can think of Local Scope as the confidential level of access.

NameError is an exception generated when using an undeclared identifier.


Local Variables and their Purpose

The variables that are declared inside of a method or function are known as Local Variables. However, I've yet to see an article describing the purpose of local variables, why they should be used, and when. We must use local variables to store the result of temporarily needed expressions that will be discarded later, such as in a function or a method.

Local variables must be used to store the result of expressions needed temporarily.


Global Scope

In Python, Global Scope is a scope that is available to all other scopes. Any declaration(s) in the Global Scope is available to all other scopes. The example below demonstrates the usage of Global Scope.

# A message to programmers of other programming languages
my_fav_prog_lang = "Python is my favourite high-level programming language. "

def print_favourite_programming_language():
    # my_fav_prog_lang is not declared here, but is still accessible
    # because it is a global variable.
    print(my_fav_prog_lang)

try:
    print(my_fav_prog_lang)
    print_favourite_programming_language()
except NameError as e:
    print(e)

Python is my favourite high-level programming language.
Python is my favourite high-level programming language.

The above example demonstrates the variable my_fav_prog_lang is available inside the function print_favourite_programming_language(). You can think of the Global Scope as the top-secret level of access.


ADVERTISEMENT

The global keyword

Sometimes, you might need to declare global variables from inside a function during the development. We could declare global variables by declaring the variable outside of any function, and it would work fine. This approach is acceptable when working on small projects. However, it could negatively affect productivity when dealing with large programs. Python understands this and, hence, provides the global keyword to declare global variables inside a function. Below is an example.

def foo_fighters():
    global no_of_foo_fighters
    no_of_foo_fighters = 1881
    print(no_of_foo_fighters)
try:
    foo_fighters()
    print(no_of_foo_fighters)
except NameError as e:
    print(e)

1881
1881

Let us break down every statement to better our understanding.

#1:  

def foo_fighters():

This statement declares that a function is being declared called foo_fighters.

#2:  

global no_of_foo_fighters

This statement informs Python that we are declaring a global variable named no_of_foo_fighters.

#3:  

no_of_foo_fighters = 1881

This statement assigns the numerical value of 1881 to the variable no_of_foo_fighters. This value will be available outside this Scope as we have assigned it to a global variable.

#4:  

print(no_of_foo_fighters)

This statement prints the value of the variable.

#5:  

try:

We are declaring a Try-Catch block to catch any exceptions .

#6:  

foo_fighters()

This statement executed the function foo_fighters.

#6:  

print(no_of_foo_fighters)

This statement prints the value of the global variable no_of_foo_fighters, as defined in statement #2.

#8 and #9:

except NameError as e:
    print(e)

These statements are trying to catch any undeclared variables. If encountered, it will print out the exception message.


Global Variables and their Purpose

The variables that are declared outside of a method or function are known as Global Variables. The purpose of global variables is to retain the value throughout the application's existence since we can use them across modules, classes, methods.

Global Variables exist throughout the application and can be used across modules, classes, and methods.


ADVERTISEMENT

Variable Shadowing

We have learned about both Local and Global Scopes. But what will happen when we have a Global and a Local variable of the same name. Let us go through an example for a better understanding.

Please copy the following code and execute it.

x = 1234
y = 747

def my_foo_method():
    x = 0
    print(f"The value of X and Y is {x}, {y}")

my_foo_method()
print(f"The value of Global Variable x is {x}")

The value of X and Y is 0, 747
The value of Global Variable x is 1234

Well, what just happened, isn't the value of x suppose to change. Actually no. A new local variable is created and assigned when a variable of the same name as the global variable is assigned a value. So, the variable x defined inside the function my_foo_method is a local variable. However, the variable y is not assigned any value inside the method but is defined as a global variable.

We can confirm this by using two in-built methods in Python: locals() and globals().

The locals() method shows the local variable available inside of the Scope. Similarly, the globals() method shows all the global variables.

Let us re-write the above example to show both available local and global variables.

x = 1234
y = 747

def my_foo_method():
    print(f"Printing local variables:\n{locals()}\n")
    x = 8
    print(f"Printing local variables\n{locals()}\n")
    print(f"Printing global variables\n{globals()}\n")

my_foo_method()
print(f"The value of Global Variable x is {x}")

Printing local variables:
{}

Printing local variables
{'x': 8}

Printing global variables
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fe62ac38520>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'test.py', '__cached__': None, 'sys': <module 'sys' (built-in)>, 'x': 1234, 'y': 747, 'my_foo_method': <function my_foo_method at 0x7fe62abd2d30>}

The value of Global Variable x is 1234

As the example demonstrates, the local variable x becomes available after being declared and assigned a value. To simply put, whenever Python accesses a variable, it first looks into the local Scope. If found, it used the value of the local variable. If not found, then it checks in the global Scope. If found, it uses the global variable value; else, it raises the NameError Exception.

A variable is first looked at in the local Scope and then the global Scope. Whichever is found earlier, that value in that Scope is utilized. If not found in both the Scope, the NameError Exception is raised.


Conclusion

This article taught us about different scopes and their purpose, declaring global variables inside the function/method using the global keyword, variables shadowing, and variable lookup hierarchy.


ADVERTISEMENT



All product names, logos, and brands are property of their respective owners.