When you start programming in Python, it is very tempting to put all your program code in a single file. There is no problem in defining functions and classes in the same file where your main program is. This option is attractive to beginners because of the ease of execution of the program and to avoid managing code in multiple files. But a single-file program approach is not scalable for medium- to large-size projects. It becomes challenging to keep track of all the various functions and classes that you define.
To overcome the situation, modular programming is the way to go for medium to large projects. Modularity is a key tool to reduce the complexity of a project. Modularization also facilitates efficient programming, easy debugging and management, collaboration, and reusability.
We will cover the following topics in this and future blogs:
• Introduction to modules and packages
• Importing modules
• Loading and initializing a module
• Writing reusable modules
• Building packages
• Accessing packages from any location
• Sharing a package
Let us start with introduction to modules and packages.
Modules in Python are Python files with a .py extension. In reality, they are a way to organize functions, classes, and variables using one or more Python files such that they are easy to manage, reuse across the different modules, and extend as the programs become complex.
A Python package is the next level of modular programming. A package is like a folder for organizing multiple modules or sub-packages, which is fundamental for sharing the modules for reusability. Python source files that use only the standard libraries are easy to share and easy to distribute using email, GitHub, and shared drives, with the only caveat being that there should be Python version compatibility. But this sharing approach will not scale for projects that have a decent number of files and have dependencies on third-party libraries and may be developed for a specific version of Python. To rescue the situation, building and sharing packages is a must for efficient sharing and reusability of Python programs.
Next, we will discuss how to import modules and the different types of import techniques supported in Python.
Importing modules
Python code in one module can get access to the Python code in another module by a process called importing modules.
To elaborate on the different module and package concepts, we will build two modules and one main script that will use those two modules. These two modules will be updated or reused throughout this blog series.
To create a new module, we will create a .py file with the name of the module. We will create a mycalculator.py file with two functions: add and subtract. The add function computes the sum of the two numbers provided to the function as arguments and returns the computed value. The subtract function computes the difference between the two numbers provided to the function as arguments and returns the computed value.
A code snippet of mycalculator.py is shown next:
# mycalculator.py with add and subtract functions
def add(x, y):
"""This function adds two numbers"""
return x + y
def subtract(x, y):
"""This function subtracts two numbers"""
return x - y
Note that the name of the module is the name of the file.
We will create a second module by adding a new file with the name myrandom.py. This module has two functions: random_1d and random_2d. The random_1d function is for generating a random number between 1 and 9 and the random_2d function is for generating a random number between 10 and 99. Note that this module is also using the random library, which is a built-in module from Python.
The code snippet of myrandom.py is shown next:
# myrandom.py with default and custom random functions
import random
def random_1d():
"""This function generates a random number between 0 \
and 9"""
return random.randint (0,9)
def random_2d():
"""This function generates a random number between 10 \
and 99"""
return random.randint (10,99)
To consume these two modules, we also created the main Python script (calcmain1.py), which imports the two modules and uses them to achieve these two calculator functions. The import statement is the most common way to import built-in or custom modules.
A code snippet of calcmain1.py is shown next:
# calcmain1.py with a main function
import mycalculator
import myrandom
def my_main( ):
""" This is a main function which generates two random\
numbers and then apply calculator functions on them """
x = myrandom.random_2d( )
y = myrandom.random_1d( )
sum = mycalculator.add(x, y)
diff = mycalculator.subtract(x, y)
print("x = {}, y = {}".format(x, y))
print("sum is {}".format(sum))
print("diff is {}".format(diff))
""" This is executed only if the special variable '__name__'
is set as main"""
if __name__ == "__main__":
my_main()
In this main script (another module), we import the two modules using the import statement. We defined the main function (my_main), which will be executed only if this script or the calcmain1 module is executed as the main program. The details of executing the main function from the main program will be covered later in the Setting special variables section. In the my_main function, we are generating two random numbers using the myrandom module and then calculating the sum and difference of the two random numbers using the mycalculator module. In the end, we are sending the results to the console using the print statement.
There are other options available to import a module, such as importlib.import_module() and the built-in __import__() function. Let's discuss how import and other alternative options works, in the next blog. Meanwhile keep practicing and experimenting.