This article is part of in the series
Last Updated: Monday 18th July 2022

Using packages is an essential part of Python programming. If packages didn’t exist, programmers would need to spend a lot of time rewriting code that’s been written before. Picture a scenario where you have to write a parser every time you want to use one – it would waste a lot of time and effort, and programmers wouldn’t get anything else done.

When you've got a large number of Python classes (or "modules"), you'll want to organize them into packages. When the number of modules (simply stated, a module might be just a file containing some classes) in any project grows significantly, it is wiser to organize them into packages – that is, placing functionally similar modules/classes in the same directory. This article will show you how to create a Python package.

What is a Package in Python?

Before you can understand what a Python package is, you must have an idea of what scripts and modules are. A script comprises code you run in a shell to accomplish a specific task. Programmers can write a script in a text editor of their choice and save it in the .py extension. Running the script is as simple as using the Python command in the terminal.

In contrast, a module is a Python program that programmers can import into other programs or directly in the interactive mode of the Python shell. The term “module” is not strictly defined in Python; it serves as an umbrella term for reusable code.

Python packages typically comprise several modules. Physically, a package is a folder of modules, and it may contain more folders that have more folders and modules.

Conceptually, a Python package is a namespace, meaning the modules in a package are bound by the package’s name and may be referenced by that name. 

Since modules are defined as reusable, importable code, every package can be defined as a module. However, every module cannot be defined as a package.

Package folders typically contain an “__init__.py” file, which indicates to Python that the directory is a package. The file may be empty or have code that needs to be executed when the package is initialized.

If you have some experience with Python programming, you may be familiar with the term “library.” In the Python language, “library” isn’t as clearly defined as a package or a module. However, when a package is published, it can be referred to as a library.

Steps to Create a Python Package

Working with Python packages is really simple. All you need to do is:

  1. Create a directory and give it your package's name.
  2. Put your classes in it.
  3. Create a __init__.py file in the directory

That's all! In order to create a Python package, it is very easy. The __init__.py file is necessary because with this file, Python will know that this directory is a Python package directory other than an ordinary directory (or folder – whatever you want to call it). Anyway, it is in this file where we'll write some import statements to import classes from our brand new package.

Example On How to Create a Python Package

In this tutorial, we will create an Animals package – which simply contains two module files named Mammals and Birds, containing the Mammals and Birds classes, respectively.

Step 1: Create the Package Directory

So, first we create a directory named Animals.

Step 2: Add Classes

Now, we create the two classes for our package. First, create a file named Mammals.py inside the Animals directory and put the following code in it:

class Mammals:
def __init__(self):
''' Constructor for this class. '''
# Create some member animals
self.members = ['Tiger', 'Elephant', 'Wild Cat']

def printMembers(self):
print('Printing members of the Mammals class')
for member in self.members:
print('\t%s ' % member)

The code is pretty much self-explanatory! The class has a property named members – which is a list of some mammals we might be interested in. It also has a method named printMembers which simply prints the list of mammals of this class! Remember, when you create a Python package, all classes must be capable of being imported, and won't be executed directly.

Next we create another class named Birds. Create a file named Birds.py inside the Animals directory and put the following code in it:

class Birds:
def __init__(self):
''' Constructor for this class. '''
# Create some member animals
self.members = ['Sparrow', 'Robin', 'Duck']

def printMembers(self):
print('Printing members of the Birds class')
for member in self.members:
print('\t%s ' % member)

This code is similar to the code we presented for the Mammals class.

Step 3: Add the __init__.py File

Finally, we create a file named __init__.py inside the Animals directory and put the following code in it:

from Mammals import Mammals
from Birds import Birds

That's it! That's all there is to it when you create a Python package. For testing, we create a simple file named test.py in the same directory where the Animals directory is located. We place the following code in the test.py file:

# Import classes from your brand new package
from Animals import Mammals
from Animals import Birds

# Create an object of Mammals class & call a method of it
myMammal = Mammals()

# Create an object of Birds class & call a method of it
myBird = Birds()

How to Use a Python Package

If you haven’t used Python packages before, we have covered everything you need to know to understand the pipeline of using Python packages in your scripts below:

Importing Python Packages

You can use the import keyword to import a package into your Python program. Assuming that you haven’t installed any packages, Python includes a large collection of packages in the standard installation. The collection of pre-installed packages is known as the Python Standard Library.

The standard library is loaded with tools for various use cases, including text processing and math. You can import a library for doing math by running the statement:

import math

You can think of the import statement as a search trigger for Python to find a module. The searchers are strictly organized and Python begins by looking for the specified module in the cache. Next, Python looks for the module in the standard library, and lastly, it searches the list of paths. 

The list of paths can be accessed after the sys module (another module in the standard library) is imported into the program.

import sys

The sys.path line in the aforementioned code returns all the directories in which Python will attempt to find a package. Sometimes, when programmers download a package and try importing it, they come up against the ImportError. Here’s an example:

>>> import gensim
Traceback (most recent call last)
   File "<stdin>", line 1, in <module>
ImportError: No module named genism

If this happens, you must check whether the package you imported is placed in one of Python’s search paths. If the package isn’t in one of those paths, you will need to expand the list of search paths to include the location of the package:

>>> sys.path.append('/home/monty/gensim-package')

Running the equivalent of the line above will provide the interpreter with one more location to look for the packages you import.

Relevance of Namespaces and Aliasing

When you import, for example, the math module into Python, you essentially initialize the math namespace. In other words, you can refer to functions and classes present in the math module using the dot notation. Here’s an example:

>>> import math
>>> math.factorial(3)

If a programmer is only interested in a specific function of a module, let’s say the factorial function of the math module, they can use the import statement to import just the relevant function, like so:

>>> from math import factorial

It is also possible to import multiple resources from the same package by separating them with a comma:

>>> from math import factorial, log

It’s important to note that there is always a small risk of variable clash involved whenever you import a package. For instance, if one of the variables in your script was named log, and you import the log function from the math package, Python will overwrite the function with your variable. This will cause bugs. 

These bugs can be avoided by importing the entirety of the package, as illustrated earlier. If you want to save time typing out the package name every time to use a module, you can import the package in the following way:

>>> import math as m
>>> m.factorial(3)

This is referred to as aliasing. Some commonly used packages have well-known aliases. For instance, the NumPy library is typically imported as “np.”

Bugs from variable clashing can also be avoided by importing all the resources from a package into your namespace, like so:

>>> from math import *

But it’s important to note that the above method poses a serious risk, since you don’t know all the names used in a package, and hence the chances of your variables being overwritten are high.