Package Structure
A package is just a directory with __init__.py. Sub-packages are nested directories, each with their own __init__.py.
# Project structure:
# myproject/
# __init__.py
# math_utils.py
# string_utils.py
# data/
# __init__.py
# loader.py
# Importing from the package:
from myproject import math_utils
from myproject.data import loader
from myproject.string_utils import clean_textThe __init__.py File
__init__.py runs when the package is imported. Use it to expose the package's public API.
# myproject/__init__.py
from .math_utils import add, subtract
from .string_utils import clean_text
__version__ = "1.0.0"
__all__ = ["add", "subtract", "clean_text"]
# Now users can do:
# from myproject import add (instead of myproject.math_utils.add)Installing Third-Party Packages with pip
pip is Python's package manager. Install packages from PyPI (Python Package Index).
# Install a package
# pip install requests
# Install specific version
# pip install requests==2.31.0
# Install from requirements file
# pip install -r requirements.txt
# List installed packages
# pip list
# Save current environment to file
# pip freeze > requirements.txtAlways use a virtual environment before pip installing packages for a project.
requirements.txt β Reproducible Environments
Share your project's dependencies so others can install exactly the same versions.
# requirements.txt
requests==2.31.0
flask==3.0.0
pandas>=2.0.0
numpy>=1.24.0
python-dotenv==1.0.0
# Install all at once:
# pip install -r requirements.txtRelative vs Absolute Imports
Inside a package, use relative imports (dot notation) to reference sibling modules.
# Inside myproject/math_utils.py:
from . import string_utils # Sibling module
from .data.loader import read_csv # Sub-package
from myproject.config import DEBUG # Absolute import