In this article, we are going to discuss what Python packages & modules are, to create our own & where they are located in our file system. We will further explore how Python modules and Python packages facilitate modular programming?
Modular programming refers to the process of breaking a large, unwieldy programming task into separate, smaller, more manageable sub-tasks or modules. Individual modules can then be cobbled together like building blocks to create a larger application.
There are several advantages to modularising code in a large application:
- Simplicity: Rather than focusing on the entire problem at hand, a module typically focuses on one relatively small portion of the problem. If we are working on a single module, we’ll have a smaller problem domain to wrap our head around. This makes development easier and less error-prone.
- Maintainability: Modules are typically designed so that they enforce logical boundaries between different problem domains. If modules are written in a way that minimises interdependency, there is a decreased likelihood that modifications to a single module will have an impact on other parts of the program. We may even be able to make changes to a module without having any knowledge of the application outside that module. This makes it more viable for a team of many programmers to work collaboratively on a large application.
- Reusability: Functionality defined in a single module can be easily reused through an appropriately defined interface by other parts of the application. This eliminates the need to duplicate code.
- Scoping: Modules typically define a separate namespace, which helps avoid collisions between identifiers in different areas of a program.
So functions, modules and packages are all constructs in Python that promote code modularisation. Let’s discuss them one by one.
A module is a Python file containing Python statements and definitions. For example, a file abc.py is a module, and we call it ‘abc’. We put similar code together in one module. This helps us modularise our code, and make it much easier to deal with. And not only that, as we earlier discussed in the introduction part that a module grants us re-usability. It means that with a module, we don’t need to write the same code again for a new project that we take up.
There are actually three different ways to define a module in Python:
- A module can be written in Python itself.
- A module can be written in C and loaded dynamically at run-time, like the regular expression module.
- A built-in module is intrinsically contained in the interpreter, like the itertools module.
Here as the topic suggests that we study about Modules and Packages in Python so the focus will mostly be on modules that are written in Python. The best thing about modules written in Python is that they are exceedingly straightforward to build. Only thing that we need to do is create a file that contains legitimate Python code and then give the file a name with a .py extension, no special syntax is necessary.
How to import a module in Python?
We need to load the module in our python code to use its functionality. Python provides two types of statements as defined below.
- The import statement
- The from-import statement
Module contents are made available to the caller with the import statement. The import statement is used to import all the functionality of one module into another. Here, we must notice that we can use the functionality of any python source file by importing that file as the module into another python source file. We can import multiple modules with a single import statement, but a module is loaded once regardless of the number of times, it has been imported into our file.
The syntax to use the import statement is given below.
|import module1,module2,…….. module n|
The from-import statement
Instead of importing the whole module into the namespace, python provides the flexibility to import only the specific attributes of a module. This can be done by using from in the import statement. The syntax to use the from-import statement is given below.
|from < module-name> import <name 1>, <name 2>..,<name n>|
The from…import statement is always better to use if we know the attributes to be imported from the module in advance. It doesn’t let our code to be heavier. We can also import all the attributes from a module by using (*).
Module Search Path
When the interpreter executes the above import statement, it searches for .py file in a list of directories assembled from the following sources:
- The directory from which the input script was run or the current directory if the interpreter is being run interactively
- The list of directories contained in the PYTHONPATH environment variable, if it is set.
- Finally, it looks into the installation-dependent default directory.
Reloading a Python Module
As we have already stated that, a module is loaded once regardless of the number of times it is imported into the python source file. However, if you want to reload the already imported module to re-execute the top-level code, python provides us with the reload() function. The syntax to use the reload() function is given below.
Using dir( ) function
The dir() function returns a sorted list of names defined in the passed module. This list contains all the sub-modules, variables and functions defined in this module. So dir() will let us check all the components of a module.
Let’s assume a situation where if we have developed a very large application that includes many modules. As the number of modules grows, it becomes difficult to keep track of them all if they are dumped into one location. This is particularly so if they have similar names or functionality. we might wish for a means of grouping and organising them. So, The packages in python facilitate the user with the application development environment by providing a hierarchical directory structure where a package contains sub-packages, modules and sub-modules. The packages are used to categorize the application-level code efficiently.
Packages allow us for a hierarchical structuring of the module namespace using dot notation. It means that if we say A.B then it stands for a submodule named B in a package named A. Packages also work in the same way like modules. As the Module help avoid collisions between global variable names, packages also help avoid collisions between module names. Two different packages like P1 and P2 can both have modules with the same name, for example, let’s say ‘A’. The submodule A of the package P1 and the submodule A of the package P2 can be totally different.
A package is imported like a “normal” module. We can have sub-packages inside the packages. We can nest the packages up to any level depending upon the application requirements. A package is basically a directory with Python files and a file with the name __init__.py. This means that every directory inside of the Python path, which contains a file named __init__.py, will be treated as a package by Python.
Initialisation of Packages
If a file named __init__.py is present in a package directory, it is invoked when the package or a module in the package is imported. This can be used for the execution of package initialisation code, such as initialisation of package-level data. __init__.py can also be used to effect automatic importing of modules from a package.
In this article about Modules and Packages in Python, we discuss the following topics as first we discuss Modular programming approach in Python, then we try to understand that what are the basic components which we used in Modular Programming, so we find here name Modules and Package. So, from there we discuss deeply what actually the modules are, and how to create them then, later on, we discuss about the locations where the Python interpreter search for a module, after that we discuss about the various ways to import a Module into our Python Code, also discuss about how to reload a module in our code, then we discuss briefly about the Packages and how to initialise them.
This will hopefully help us to better understand how to gain access to the functionality available in the many third-party and built-in modules available in Python. Additionally, if we are going to develop our own application by creating our own modules and packages. It will really help us to organise and modularise our code, which makes coding, maintenance and debugging easier.
By Mayank Mishra