top of page

Mastering Python Packages: Creation, Enhancement, and Portability


I. Introduction to Python Packages


Python packages are a crucial part of software engineering, providing reusable code modules that perform common tasks. Think of these packages as Lego blocks. Just as Lego blocks can be assembled into various structures depending on what you want to build, Python packages can be combined in different ways to create a wide range of software applications.


1. Understanding Python packages


A Python package is a directory that contains Python modules (which are simply Python files, with the ".py" extension) and a special file called "init.py". This structure allows for the organization of related modules into a well-structured, hierarchical namespace.

my_package/
    __init__.py
    module1.py
    module2.py


Packages help avoid collisions between global variable names. For example, if you have a function named run() in a module and the same function name in a different module, packaging can help you segregate them to avoid confusion or potential errors.


2. The Importance and Usage of Python Packages in Software Engineering


In software engineering, Python packages play a vital role. They help in code reusability and decomposition, and in structuring a program into modular, manageable parts. Just as a library contains different sections based on book genres, Python packages categorize similar modules together, making code easier to find and use.


II. Creating a Basic Python Package



1. The Structure of a Python Package


The structure of a Python package involves several components, but we'll start with the basics: the package directory and the "init.py" file.

A Python package is like a closet. The closet (the package directory) contains clothes (Python modules). The "init.py" file is like the closet light - it illuminates the closet, making Python recognize the directory as a package.


a. Introduction to the Basic Structure of a Python Package


A Python package comprises a directory that contains one or more ".py" files and a special "init.py" file.

my_package/
    __init__.py
    module1.py


b. The Importance of the Directory Name


The directory name becomes the package name. So, if you want to import a module from the package, you would use import my_package.module1.


c. Guidelines on How to Name a Package According to PEP 8


According to PEP 8, Python's official style guide, package names should be all lower case and not contain underscores. This improves readability and prevents potential errors.


2. Implementing a Python Package


Now, let's get our hands dirty by creating a Python package.


a. Creating a Directory for the Package


First, we create a directory named "my_package".

mkdir my_package


b. Naming the Python File as "init.py"


Next, create an empty file named "init.py" inside the "my_package" directory. You can use the touch command to create this file:

touch my_package/__init__.py


c. Explanation of How "init.py" Enables Python to Recognize the Directory as a

Package


The "init.py" file is a special Python file that is always executed when a package (or a module inside it) is imported. It can be left empty, but it must be present for Python to recognize the directory as a package.


3. Importing a Local Python Package


After creating our package, we can now import it into a Python script.


a. Understanding the Relative Location of the Script File to the Package Directory


The script file that will import the package should be in the same directory level as the package or in a higher level. Here's an example of a directory structure:

project_directory/
    my_script.py
    my_package/
        __init__.py
        module1.py


b. How to Import the Created Package


In "my_script.py", you can import the package or modules from the package as follows:

import my_package.module1

or

from my_package import module1


c. Checking the Package Details Using the "help" Function


You can check details of your package using the help() function.

help(my_package)

The above command will print information about the "my_package" package.


III. Enhancing Python Packages


Once we have a basic Python package, we can add functionalities to it, making it more useful and robust. This process is like upgrading your basic bicycle with gears and suspension, enhancing its functionality and overall performance.


1. Adding Functionality to a Python Package


a. Understanding Package File Structure


Let's now add more files to our package. Each file can be considered a module

that contains functions, classes, and variables.

my_package/
    __init__.py
    module1.py
    utils.py


b. The Guidelines for File Naming in a Python Package


As per PEP 8, Python filenames (hence, module names) should be all lowercase and can include underscores to improve readability.


c. Adding a File, "utils.py", to the Package Directory


Let's add a "utils.py" file to our package.

touch my_package/utils.py


2. Implementing Functionality


a. Writing a Function in the "utils.py" File


We'll write a simple function in "utils.py" that adds two numbers.

# my_package/utils.py

def add_numbers(num1, num2):
    return num1 + num2


b. How to Import and Use Functions from a Package


We can now import this function from the package in a Python script.

from my_package.utils import add_numbers

result = add_numbers(5, 10)
print(result)  # Output: 15


3. Improving Accessibility with "init.py"


Just as the table of contents in a book makes it easy to find specific chapters, the "init.py" file can improve the accessibility of functions and classes in a Python package.


a. Making Functions More Accessible Using "init.py"


We can import the "add_numbers" function in "init.py" to make it more accessible.

# my_package/__init__.py

from .utils import add_numbers


b. Using Relative Import to Import a Function in the "init.py" File


The above example uses a relative import, which means it's importing something from the same package. The . before utils denotes that it's in the same package.


Now, we can import the function directly from the package.

from my_package import add_numbers

result = add_numbers(5, 10)
print(result)  # Output: 15


4. Extending the Structure of a Python Package


A Python package can contain subpackages, creating a package structure that mirrors your project's architecture. This is like adding more sections to your library, such as an area for children's books or a reference section.


a. Extending the Package with Multiple Submodules


A package can contain multiple modules and subpackages, allowing for a more complex package structure.

my_package/
    __init__.py
    utils.py
    subpackage1/
        __init__.py
        module2.py


b. Importing Key Functionality in "init.py"


In the "init.py" file of the main package and subpackages, you can import key functionalities to make them more accessible.


c. Discussion on What is Considered 'Key' Functionality


'Key' functionality would be the functions, classes, or variables that users of your package will use most frequently. By importing these in "init.py", you make it easier for users to access them.


d. Introducing Subpackages within a Python Package


A subpackage is a package inside a package. Subpackages allow you to further organize your code.

my_package/
    __init__.py
    utils.py
    subpackage1/
        __init__.py
        module2.py


IV. Making Python Packages Portable


A crucial aspect of Python package development is making the package portable, meaning it can be used on any system without issues. This is analogous to packaging a physical product: you need to ensure it's packed in a way that makes it safe and easy to transport, and that it comes with instructions on how to assemble and use it.


1. Sharing a Python Package


There are a few steps to prepare a Python package for sharing. First, you need to ensure the package structure is correct. You should also include some additional files that provide information about the package and its dependencies. This is like including a user manual with your product, giving the user everything they need to use it effectively.


2. Portable Package Structure


The package structure for a portable Python package is a little more complex than for a basic package. You should include a "setup.py" file and a "requirements.txt" file in the root directory of the package.

my_package/
    __init__.py
    utils.py
    setup.py
    requirements.txt


3. Contents of the "requirements.txt" File


A "requirements.txt" file lists the dependencies of your package. It's like a shopping list of ingredients needed to make a recipe. This file allows users to easily install all dependencies with the command pip install -r requirements.txt.

The file should contain a list of package names, and can optionally specify versions.

numpy
pandas>=1.0.0
scikit-learn


4. Contents of the "setup.py" File


The "setup.py" file provides information about your package, such as its name, version, and author, and lists its dependencies. It's like the product information page in an online shop. You use the "setuptools" package to create this file.


Here is an example of a simple "setup.py" file:

from setuptools import setup, find_packages

setup(
    name="my_package",
    version="0.1",
    author="Your Name",
    packages=find_packages(),
    install_requires=[
        "numpy",
        "pandas>=1.0.0",
        "scikit-learn"
    ],
)


5. Differences Between "install_requires" and "requirements.txt"


The "install_requires" parameter in "setup.py" and the "requirements.txt" file both specify package dependencies. The main difference is that "install_requires" is used when others install your package using pip install your-package, while "requirements.txt" is typically used when someone clones your code and wants to install the dependencies.


6. Installing the Python Package


Once your package structure is set up correctly, you can install the package with pip. This installs the package at an environment level, so it can be imported into any Python script using the same environment.

pip install .


This command tells pip to install the package in the current directory (represented by .).


After these steps, you'll have a portable Python package that you can share with others or even distribute publicly.


Congratulations! You now understand Python packages, from their basic structure to making them portable. It's a big topic, but don't be intimidated. Just like building a house, start with a solid foundation and keep adding one brick at a time. Happy coding!

bottom of page