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.
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.
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.
Term
Description
Module
A single Python script (.py file)
Package
A directory structure that groups modules
Library
A 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.
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.
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
Type
Advantages
Disadvantages
Absolute Import
High readability and clear package structure
May require long path specifications
Relative Import
Easy to move code and allows concise statements
May 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.
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.
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.
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 names → use all‑lowercase words
mypackage, utilities, datahandler
Module names → use 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.
Error
Cause
Solution
ModuleNotFoundError
module is not installed
pip install package_name
ImportError
import path is incorrect
Try an absolute import
Solutions for ModuleNotFoundError
Check whether the package is installed
pip list | grep package_name
If it is not installed, add it with pip install
pip install package_name
Solutions for ImportError
Try an absolute import
from mypackage.module1 import greet
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.
Verify that the upload succeeded
twine check dist/*
Specify the correct package name
pip install mypackage
Wait for PyPI to reflect the upload
It may take a few minutes for the package to appear on PyPI after upload.
__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
Follow package naming conventions
Use simple, lowercase names and keep readability in mind.
Leverage virtual environments (venv)
Encourage development that does not depend on the global environment.
Always manage requirements.txt
Prevent issues in team development and deployment.
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″>