We usually organize our files in different folders and subfolders based on criteria so that they can be managed quickly and efficiently. A Python module may contain several classes, functions, variables, etc., whereas a Python package can contain several modules. In simpler terms, a package is a folder that contains various modules as files.
The meaning of Packages lies in the word itself. Packages do the work of organizing files in Python. Physically a package is a folder containing sub-packages or one or more modules (or files). They provide a well-defined organizational hierarchy of modules in Python. Packages usually are named such that their usage is apparent to the user. Python packages ensure modularity by dividing the packages into sub-packages, making the project easier to manage and conceptually clear.
To better understand what Packages in Python mean, let’s take an example from real life. Your family is shifting to a new apartment. Your mom has asked you to pack your books, CDs, and toys so that it’s easy to unpack and organize them in your new house. The simplest way to do this would be to pack these items separately into three unique packages ( boxes for CDs, books, and toys, respectively) and name them based on their utility. Furthermore, you can also add sections to your book package based on the genre of books. We can do the same thing for CDs and toys as well.
Have you come across this way of organization somewhere? The most common example would be that of files on your phone. All your files would be saved in a folder that could further be distinguished based on the source (WhatsApp Documents, Downloads, etc.).
Every package in Python must contain an __init__.py file since it identifies the folder as a package. It generally contains the initialization code but may also be left empty. A possible hierarchical representation of the shifting items package in the first example can be given below. Here, shifting items is our main package. We further divide this into three sub packages: books, CDs and toys. Each package and subpackage contains the mandatory __init__.py file. Further, the sub packages contain files based on their utility. Books contain two files fiction.py and non_fiction.py, the package CDs contain music.py and dvd.py, and the package toys contain soft_toys.py and games.py.
Importing Module from a Package in Python
Packages help in ensuring the reusability of code. To access any module or file from a Python package, use an import statement in the Python source file where you want to access it. Import of modules from Python Packages is done using the dot operator (.). Importing modules and packages helps us make use of existing functions and code that can speed up our work.
Where import is a keyword used to import the module, module1 is the module to be imported. The other modules enclosed in brackets are optional and can be mentioned only when more than 1 module is to be imported.
Consider the writing package given below.
To use the edit module from the writing package in a new file test.py that you have created, you write the following code in the test.py:
To access a function called plagiarism_check() of the edit module, you use the following code:
The calling method seems lengthy and confusing, right? Another way to import a module would be to simply import the package prefix instead of the whole package and call the function required directly.
However, the above method may cause problems when 2 or more packages have similarly named functions, and the call may be ambiguous. Thus, this method is avoided in most cases.
Installing a Python Package Globally
To ensure system-wide use of the Python package just created, you need to run the setup script. This script uses the setup() function from the setuptools module. As a prerequisite, you need to have the latest versions of pip and setuptools installed on your system. Pip and setuptools are usually installed along with the Python binary installers. To upgrade the version of pip, use the following command:
Once you confirm that you have the latest versions of pip and setuptools installed, you can create a setup.py file in the main package (Writing) folder. The setup() function that will be imported here takes various arguments like the package's name, version, description, author, license, etc. The zip_safe argument is used to know the mode of storage of the package (compressed or uncompressed).
Now to install the Writing package, open a terminal in your parent package folder (Writing) and type in the following command:
The Writing package, which contains functions to assist writing (like count_words which is used to count the number of words in a string) will now be available for use anywhere on the system and can be imported using any script or interpreter by using the following commands:
This is how you create a system-wide package. If you want to create a package that can be used by users globally, follow the following steps:
- Organize your package well with a readme.md, license and other files. Give an easy-to-understand and memorable name for your package.
- Register an account on https://pypi.org.
- Use twine upload dist/* to upload your package on PyPi and enter the credentials you used to create the account. The package will be uploaded directly to PyPi.
- You can now install your Python package from PyPi using the command python -m pip install [package_name] in your terminal.
Import Statement in Python
The files in packages that contain Python code are called modules. Modules are used to break down large code into smaller and more understandable parts. Commonly used code (functions) can be written in the form of modules and imported as and when needed, thus ensuring the reusability of code.
Let’s create a function prod(x,y) to multiply two numbers x and y, which are passed as arguments to a function, and store it in a module named product.py.
To import the prod function in another module or use it in the interactive interpreter shell of Python, type:
This statement does not import the module's functions into the symbol table. To access functions of the given module, we use the dot (.) operator as follows:
Python has a lot of in-built modules which can be accessed in the same way. For example, to print the value of pi, we can import the math module.
Importing Attributes Using the From Import Statement in Python
We can also import individual attributes from the module. This reduces the complexity of writing the function calls.
In the previous example, we could import pi directly from the math module as follows:
You can import more than one attribute by separating them with commas (,). In the below example, we import the functions pi, floor (used to find the smallest integer greater than or equal to the given number) and fabs (used to find the absolute value of a number) from the math package.
Importing Modules Using the From Import * Statement in Python
To import all modules' definitions, use the asterisk (*) operator.
Importing Modules in Python Using the Import as Statement
You can alter how a module is called in your program by aliasing it, i.e. giving it another name. The as operator is used for this purpose.
Importing Class/Functions from Module in Python
To import classes or functions from a module in Python, use the following syntax:
Example: To import the prod function from the math module, which is used to calculate the product of 2 given numbers, we import prod specifically as shown. We then can access prod() directly without using the dot (.) operator.
Import User-defined Module in Python
To import modules defined by the user from different code files, use the following syntax:
Example: Consider the file example.py having a function val(x,y) defined as follows:
To import the val function in another module or use it in the interactive interpreter shell of Python, type:
This statement does not import the module's functions into the symbol table (a table in Python generated by the Python compiler used to calculate the scope of identifiers). To access functions of the given module, we use the dot (.) operator as follows:
Importing from Another Directory in Python
Usually, when we import modules, the called modules are placed in the same directory as the calling modules. To import modules from another directory (collection of files in a path different from the present working directory), we use the importlib library by calling the following import statement.
Methods like exec_module (used to execute a module) and module_from_spec (used to create a new module from the given specifications) are used to satisfy the purpose.
Example: Consider two modules: upperCase.py (which is to be imported), and final.py (the one that imports upperCase.py). The directory structure is as follows:
You will realize that upperCase.py and MainCodes are in a common directory named PythonCode. final.py is placed in the MainCodes subdirectory. Thus, upperCase.py and final.py do not share the same directory.
The modules upperCase.py and final.py are defined as follows:
upperCase.py - This contains a function called upperCase which converts the string sent as an argument to upperCase and returns the new string. This is done by first converting the argument to a string (to ensure that no ambiguity in the type of argument remains) and then using the upper() method to fulfill the required purpose.
final.py - This is the file where the function upperCase needs to be imported. Since upperCase lies in another directory (as shown in the directory structure above), we import the importlib and importlib.util packages. A function called module_directory contains two parameters: name_module and path representing the module's name and the module's path to be imported, respectively. A variable P is used to save the ModuleSpec, i.e. all the import-related information required to load the module. It is done by calling the spec_from_file method from importlib.util after passing the name_module and path as parameters. Another variable import_module saves the module from the ModuleSpec saved in the variable P. The exec_module is used to execute the import_module module in its namespace. The import_module is then returned by the function. A result variable is used to call the module_directory function. The upperCase function is then called using a dot (.) operator.
Importing Class from Another File in Python
We just saw how to import functions from files in other directories. What if you want to import a class from another file? The importlib library is used to import classes from another file, which can be saved in the same directory or another.
Example: Consider 2 files: calc.py (which is to be imported), and final.py (the one that imports calc.py). The directory structure is as follows:
You will realize that calc.py and MainCodes are in a common directory named PythonCode. final.py is placed in the MainCodes subdirectory. Thus, calc.py and final.py do not share the same directory.
The modules calc.py and final.py are defined as follows:
calc.py- This contains a class called calc which has 3 user-defined class functions namely add(), sub() and mul() used to implement addition, subtraction and multiplication of 2 numbers respectively. In addition to that, calc.py also contains a function named greet() which when called, prints ‘Hello World!’ on the screen.
final.py - This is the file where the class calc needs to be imported. Since calc lies in another directory (as shown in the directory structure above), we import the importlib and importlib.util packages. A function called module_directory contains two parameters: name_module and path that represent the module's name and the module's path to be imported respectively. A variable P is used to save the ModuleSpec, i.e. all the import-related information required to load the module. This is done by calling the spec_from_file method from importlib.util after passing the name_module and path as parameters. Another variable import_module saves the module from the ModuleSpec saved in the variable P. The exec_module is used to execute the import_module module in its own namespace. The import_module is then returned by the function.
A result variable is used to call the module_directory function. An object named object is then created by instantiating the class calc from the imported module. Different functions of the calc class can be then called by using the dot (.) operator as shown in the code below.
In this article, we have learned the following points:
- Python packages help in modularizing the code while ensuring code reusability.
- Common in-built Python packages include pip and setuptools.
- Classes, functions, modules, etc., can be imported from other modules using the import keyword.
- The' as' keyword refers to a module by another name.
- importlib is used while importing classes and functions from other directories.
- You can further use Python packages to build apps for text classification, sentimental analysis, calendar functionality, and integrate into existing apps using different APIs.