Python Package Creation, Management & Distribution Guide

目次

1. Introduction

The Importance of Packages in Python

Python packages are collections of multiple modules that provide an essential mechanism for facilitating code reuse and management. In large-scale projects, properly structuring packages improves code readability and maintainability. The Python ecosystem already includes many useful packages (libraries), but creating your own packages and applying them to projects enables more flexible development.

Purpose and Overview of This Article

In this article, we will explain the following topics about Python packages in detail.
  • Fundamental concepts and structure of packages
  • How to create your own package
  • How to import packages
  • Managing packages using pip
  • Steps to publish to PyPI (Python Package Index)
  • Common errors and their solutions (FAQ)
By reading this guide, you will systematically learn about Python packages and be able to apply them in practice.

Intended Audience

This article is intended for the following readers.
  • Those who understand basic Python syntax and have experience writing simple scripts or functions
  • Those who want to organize Python projects and write reusable code
  • Those who want to create their own packages and publish them to PyPI
For these readers, this article is structured to deepen your understanding of Python packages and provide practical, useful information.

2. What Are Python Packages?

Differences Between Packages and Modules

In Python, the concepts of “modules” and “packages” exist to help organize code properly and make it easier to reuse.
  • Module (Module) Refers to a single Python script (.py file). For example, a Python file like the one below constitutes a module.
  # sample_module.py
  def greet():
      return "Hello, Python!"
  • Package (Package) A directory that groups multiple modules together and typically contains an __init__.py file. Using packages allows you to organize and manage multiple modules.
  mypackage/
  ├── __init__.py
  ├── module1.py
  ├── module2.py

Differences from Libraries

The term “library” is also commonly used, but a library is a broader concept that includes packages and modules. Specifically, a library can be thought of as a collection of packages that provides a set of tools for specific functionality.
TermDescription
ModuleA single Python script (.py file)
PackageA directory structure that groups modules
LibraryA collection of software that includes multiple packages
For example, requests and numpy are packages, while libraries such as SciPy and Django combine multiple packages.

Purpose of __init__.py

A package directory requires a special file called __init__.py. Its presence tells Python to recognize the directory as a package.

Basics of __init__.py

__init__.py can be empty, but you can also define initialization settings and key functions for the package as shown below.
# mypackage/__init__.py
from .module1 import greet

def welcome():
    return "Welcome to mypackage!"
With this setup, when you import mypackage from outside the package, you can use the greet() function directly.
from mypackage import greet
print(greet())  # Hello, Python!

Namespace Packages

Since Python 3.3, packages can be recognized without an __init__.py file via “Namespace Packages”. However, for compatibility reasons, it is common to include an __init__.py.

Summary

  • Module is a single .py file, while a package has a directory structure containing multiple modules.
  • Library is a collection of software that combines packages and modules.
  • __init__.py is required to identify a package and can define initialization settings and convenient imports.
  • Since Python 3.3, packages without __init__.py (namespace packages) are also possible.
RUNTEQ(ランテック)|超実戦型エンジニア育成スクール

3. How to Create a Python Package

Basic Package Directory Structure

Python packages function correctly by following a specific directory structure. Below is an example of a simple package directory layout.
mypackage/
├── __init__.py  # package identifier file
├── module1.py   # module 1
├── module2.py   # module 2
└── subpackage/  # subpackage
    ├── __init__.py
    ├── submodule1.py
    └── submodule2.py

Roles of Each File

  • mypackage/ :package root directory
  • __init__.py :file that indicates this folder is a package (optional for Python 3.3 and later)
  • module1.pymodule2.py :modules within the package
  • subpackage/ :subpackage (contains additional modules inside)

__init__.py Creation and Role

__init__.py identifies the package and defines initialization code when the package is imported.

Simple __init__.py

Even just creating an empty __init__.py as shown below makes it function as a package.
# mypackage/__init__.py

Adding Initial Settings to __init__.py

Here’s a more practical example of __init__.py.
# mypackage/__init__.py
from .module1 import greet

def welcome():
    return "Welcome to mypackage!"
With this setup, importing the package makes the greet() function available.
from mypackage import greet
print(greet())  # "Hello, Python!"

Creating Modules and Subpackages

Creating a Module (module1.py)

Each module can define its own functions and classes.
# mypackage/module1.py
def greet():
    return "Hello, Python!"

Creating a Subpackage (subpackage/)

Creating a subpackage allows you to further divide functionality.
mypackage/
└── subpackage/
    ├── __init__.py
    ├── submodule1.py
    └── submodule2.py
Defining functions in the subpackage’s __init__.py makes it easy to import.
# mypackage/subpackage/__init__.py
from .submodule1 import sub_function

def subpackage_greeting():
    return "Hello from subpackage!"

Verifying the Package

To verify the created package, use Python’s interactive shell.
  1. Navigate to the parent directory of mypackage
   cd path/to/your/package
  1. Open the Python shell
   python
  1. Import mypackage and run functions
   import mypackage
   print(mypackage.welcome())  # "Welcome to mypackage!"

Summary

  • Python packages consist of directories and __init__.py.
  • __init__.py is used for package identification and initialization.
  • Leveraging modules and subpackages makes code organization easier.
  • After creation, verify in the Python shell to ensure it works correctly.

4. How to Import Packages

Importing Modules Within a Package

When using Python packages, you typically use an import statement. For example, consider the following package structure.
mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/
    ├── __init__.py
    ├── submodule1.py

Direct Module Import

Assume that module1.py defines a greet() function.
# mypackage/module1.py
def greet():
    return "Hello from module1!"
To use this function, you can use an import statement as follows.
import mypackage.module1

print(mypackage.module1.greet())  # Hello from module1!

from Keyword Import

If you want a more concise import, you can use the from keyword.
from mypackage.module1 import greet

print(greet())  # Hello from module1!

Differences Between Relative and Absolute Imports

In Python, there are two ways to import modules within a package: relative imports and absolute imports.

Absolute Import

This method imports by specifying the path from the package’s root directory.
# mypackage/module2.py
from mypackage.module1 import greet

def call_greet():
    return greet()
The advantage of this approach is high readability and clear representation of the package structure.

Relative Import

It imports other modules relative to the current module’s location. You can use a . (dot) to refer to another module within the same package.
# mypackage/module2.py
from .module1 import greet

def call_greet():
    return greet()
In relative imports, the number of . indicates how many parent directories to traverse.
  • from .module1 import greet → import greet() from module1.py in the same package
  • from ..subpackage.submodule1 import some_function → import some_function from subpackage/submodule1.py one level up

Relative Import vs Absolute Import

TypeAdvantagesDisadvantages
Absolute ImportHigh readability and clear package structureMay require long path specifications
Relative ImportEasy to move code and allows concise statementsMay cause errors when run from outside the package
Relative imports can raise ImportError when the script is run from outside the package. Therefore, for large projects, absolute imports are recommended.

Simplifying Imports Using __init__.py

By defining specific functions or classes in __init__.py, you can simplify package imports.
# mypackage/__init__.py
from .module1 import greet
With this setup, you can import the function in a simple way as follows.
from mypackage import greet

print(greet())  # Hello from module1!

Summary

  • Module import methods include two types: import and from ... import.
  • Absolute imports have high readability with explicit path specifications, but can become verbose.
  • Relative imports are concise, but can cause ImportError depending on how the script is executed.
  • By leveraging __init__.py, you can simplify package imports.
侍エンジニア塾

5. Managing Python Packages (Using pip)

pip for Installing and Uninstalling Packages

In Python, you can easily install external libraries using pip. You can download them from the official Python Package Index (PyPI) and add them to your environment.

Installing Packages

Running the following command will install the specified package.
pip install package_name
For example, to install the requests library:
pip install requests
Once installed, you can import it in your Python scripts.
import requests

response = requests.get("https://example.com")
print(response.status_code)

Uninstalling Packages

If a package is no longer needed, use pip uninstall to remove it.
pip uninstall package_name
For example, to uninstall requests:
pip uninstall requests
When you run it, you’ll be prompted for confirmation; entering y will delete it.

pip freeze and requirements.txt for Environment Management

It’s common to create a requirements.txt file to share the list of packages used in a project.

Outputting the Current Package List

To list the packages installed in a project, use the following command.
pip freeze
Example output:
requests==2.26.0
numpy==1.21.2
pandas==1.3.3
Saving this list to requirements.txt lets you easily reproduce the same packages in other environments.
pip freeze > requirements.txt

Bulk Installing Packages from requirements.txt

When setting up a project in another environment, you can install all packages from requirements.txt.
pip install -r requirements.txt

Package Management in Virtual Environments (Using venv)

In Python, it’s common to use virtual environments (venv) to manage separate package environments for each project. Using a virtual environment allows development without affecting the system-wide package configuration.

Creating a Virtual Environment

Navigate to your project directory and create a virtual environment with the following command.
python -m venv myenv
A virtual environment named myenv/ will be created, containing a Python runtime.

Activating the Virtual Environment

To use the created virtual environment, run the following command.
  • Windows (PowerShell)
  myenvScriptsActivate
  • Mac / Linux
  source myenv/bin/activate
When the virtual environment is activated, the command line will show a prefix like (myenv).

Package Management Inside the Virtual Environment

Inside the virtual environment, you can install packages normally using pip.
pip install flask
To exit the virtual environment, run the following command.
deactivate

Package Version Management

Checking Versions of Installed Packages

To check the versions of installed packages, use the following command.
pip list
Or, to view detailed information about a specific package, use pip show.
pip show package_name
Example:
pip show numpy
Example output:
Name: numpy
Version: 1.21.2
Summary: NumPy is the fundamental package for array computing with Python.

Upgrading Packages to the Latest Version

To upgrade an existing package to the latest version, run the following command.
pip install --upgrade package_name
For example, to upgrade requests to the latest version:
pip install --upgrade requests
If you want to upgrade all packages at once, use the following command.
pip list --outdated | awk '{print $1}' | xargs pip install --upgrade
(Note: awk and xargs are available on Linux/Mac.)

Summary

  • You can install packages with pip install package_name and remove them with pip uninstall.
  • Using pip freeze > requirements.txt makes it easier to manage project dependencies.
  • Using virtual environments (venv) lets you create isolated environments for each project.
  • You can check installed package versions with pip list and update them with pip install --upgrade.

6. How to Distribute Python Packages

Package configuration using pyproject.toml

In Python, it is recommended to use pyproject.toml when creating and distributing packages. This file contains the package’s metadata and dependency information.

Basic structure of pyproject.toml

Create a pyproject.toml in the project’s root directory and write it as follows.
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage" version = "0.1.0" description = "My Python package" authors = [{ name = "Your Name", email = "your_email@example.com" }] license = { text = "MIT" } dependencies = ["requests", "numpy"]
With this configuration, building and distributing the package can be done smoothly.

Creating packages using setuptools

Use setuptools to create distributable formats (such as sdist and wheel).

Preparing the package

Set up a directory structure like the following.
mypackage/
├── mypackage/
│   ├── __init__.py
│   ├── module1.py
│   ├── module2.py
├── pyproject.toml
├── README.md
└── LICENSE
  • mypackage/: the actual package code
  • pyproject.toml: package configuration file
  • README.md: package description
  • LICENSE: license information

Building the package

In a terminal, navigate to the project’s root directory and run the following command.
python -m build
This generates .tar.gz (source distribution) and .whl (wheel) files in the dist/ directory.
dist/
├── mypackage-0.1.0-py3-none-any.whl
├── mypackage-0.1.0.tar.gz

Uploading to PyPI using twine

To publish a package to PyPI, use twine.

Testing on TestPyPI

It is recommended to verify the package on TestPyPI before uploading to the production environment. First, install twine.
pip install twine
Next, upload the package to TestPyPI.
python -m twine upload --repository testpypi dist/*
To install the package from TestPyPI, use the following command.
pip install --index-url https://test.pypi.org/simple/ mypackage

Uploading to PyPI (production)

After confirming on TestPyPI, upload to the production environment, PyPI.
python -m twine upload dist/*
After uploading, you can search for the package on the official PyPI site (https://pypi.org/) to verify that it is published.

Installing the package from PyPI

The published package can be installed with the following command.
pip install mypackage

Summary

  • It is recommended to manage package information using pyproject.toml.
  • Convert to distributable formats (sdist, whl) using python -m build.
  • After verifying on TestPyPI using twine, upload to PyPI.
  • The published package can be installed with pip install.

7. Frequently Asked Questions (FAQ)

__init__.py is always required?

Q: Is __init__.py required? A: Starting with Python 3.3, packages can be recognized without an __init__.py as a “namespace package”. However, in many projects it is common to create an __init__.py explicitly.
# mypackage/__init__.py
Adding this file lets you define package initialization code and simplifies imports.

What is the difference between relative and absolute imports?

Q: What is the difference between relative and absolute imports? A: In Python, there are two ways to import modules: absolute imports and relative imports.
  • Absolute imports
  from mypackage.module1 import greet
  • Specify the path from the root directory, making the package structure clear
  • Highly readable and less prone to errors
  • Relative imports
  from .module1 import greet
  • Use a . (dot) to refer to modules within the same package
  • May raise ImportError when run from outside the package

Are there naming conventions for packages?

Q: Are there rules for naming Python packages and modules? A: PEP8 (the official Python style guide) recommends the following naming conventions.
  • Package namesuse all‑lowercase words
  mypackage, utilities, datahandler
  • Module namesuse short, clear lowercase words
  module1, parser, reader

What is the purpose of requirements.txt?

Q: What is requirements.txt used for? A: requirements.txt lists the packages used in a project and is used to maintain reproducible environments. To create it, run the following command.
pip freeze > requirements.txt
To install the same packages in another environment, run:
pip install -r requirements.txt

Why do ModuleNotFoundError and ImportError occur?

Q: Please explain the causes and solutions for ModuleNotFoundError and ImportError. A: These errors occur when Python cannot locate a module or package properly.
ErrorCauseSolution
ModuleNotFoundErrormodule is not installedpip install package_name
ImportErrorimport path is incorrectTry an absolute import

Solutions for ModuleNotFoundError

  1. Check whether the package is installed
   pip list | grep package_name
  1. If it is not installed, add it with pip install
   pip install package_name

Solutions for ImportError

  1. Try an absolute import
   from mypackage.module1 import greet
  1. Check the Python execution directory
   import sys
   print(sys.path)

Why can’t I pip install after uploading to PyPI?

Q: I uploaded a package to PyPI, but I can’t pip install it. What should I do? A: Please check the following points.
  1. Verify that the upload succeeded
   twine check dist/*
  1. Specify the correct package name
   pip install mypackage
  1. Wait for PyPI to reflect the upload
  • It may take a few minutes for the package to appear on PyPI after upload.
<ol=”3″>
  • If you uploaded to TestPyPI
  • Specify --index-url instead of plain pip install
   pip install --index-url https://test.pypi.org/simple/ mypackage

Summary

  • __init__.py is not required from Python 3.3 onward, but adding it is common.
  • Absolute imports are recommended because they are more readable and less error‑prone.
  • Using requirements.txt makes it easy to manage package dependencies.
  • ModuleNotFoundError and ImportError can be resolved by checking package installation status and import paths.

8. Summary

Basic Concepts of Python Packages

  • Module is a single .py file, and a Package is a directory that groups multiple modules.
  • Library is a collection of software that bundles multiple packages and modules.
  • __init__.py helps identify a package and simplify imports.

How to Create a Python Package

  • Create a mypackage/ directory and add __init__.py to have it recognized as a package.
  • Split modules appropriately and design code for easy reuse.
  • Using absolute imports makes module references within a package clear.

Managing Packages

  • Install a package with pip install package_name and remove it with pip uninstall package_name.
  • Using pip freeze > requirements.txt makes it easier to reproduce a project’s environment.
  • Create a virtual environment with python -m venv myenv to build an isolated environment per project.

Distributing Packages

  • Use pyproject.toml to manage package metadata and build in a standard format.
  • Build the package into the dist/ directory with python -m build.
  • Use twine to test on TestPyPI, and if everything looks good, upload to PyPI.
  • The published package can be easily installed with pip install mypackage.

Common Errors and Solutions

  • For ModuleNotFoundError, check that the package is installed and verify the sys.path settings.
  • For ImportError, try using absolute imports instead of relative imports.
  • Use pip list --outdated to check for newer package versions and upgrade as needed.

Best Practices for Python Package Management

  1. Follow package naming conventions
  • Use simple, lowercase names and keep readability in mind.
  1. Leverage virtual environments (venv)
  • Encourage development that does not depend on the global environment.
  1. Always manage requirements.txt
  • Prevent issues in team development and deployment.
  1. Test on TestPyPI before publishing to PyPI
  • Prevent errors in advance and ensure quality.

Summary and Future Learning

Understanding Python packages and managing and distributing them properly enables efficient development. In particular, designing with package reusability in mind and adopting a development style that leverages virtual environments allows you to build more robust Python projects. Going forward, you can deepen your understanding by learning about topics such as:
  • Advanced package development (adding custom scripts, introducing C extensions)
  • Automated package deployment using CI/CD
  • Environment setup combined with Docker
I hope this article helps you effectively leverage Python packages. Thank you for reading to the end!</ol=”3″>