Packages
Learn what a Python package is, how to organize modules into one, relative vs absolute imports, and how packages differ from modules, libraries, and frameworks.
Introduction
A single module is great for a handful of functions, but real applications quickly grow beyond one file. Python packages solve this by letting you group related modules together into folders, the same way you would organize files into folders on your computer.
In this lesson, you will learn what a package actually is, how to structure a small multi-file project as one, the difference between relative and absolute imports, and how the terms module, package, library, and framework relate to each other.
- What a package is and the role of __init__.py.
- How to organize a small project into a package with multiple modules.
- The difference between absolute and relative imports.
- How to clearly distinguish modules, packages, libraries, and frameworks.
What is a Package?
A package is a directory that contains a collection of modules, along with a special file named __init__.py that tells Python to treat that directory as a package rather than just an ordinary folder.
It's a Folder
A package is simply a directory — but one Python recognizes as importable.
__init__.py
This file (often empty) marks the folder as a package Python can import from.
Groups Related Modules
A package bundles several related modules under one importable name.
Can Contain Sub-Packages
Packages can nest inside other packages to model larger project structures.
In modern Python (3.3+), a folder can technically be imported as a "namespace package" even without __init__.py. However, including an __init__.py file — even empty — remains the clearest, most widely used, and most compatible way to define a regular package.
Organizing a Project into a Package
Imagine you are building a small toolkit for a shop app, with separate modules for discounts and tax calculations, grouped inside a package named shop.
shop/
__init__.py
discounts.py
tax.py
main.pydef apply_discount(price, percent):
return price - (price * percent / 100)def add_tax(price, rate=0.05):
return price + (price * rate)# Can be left empty, or used to expose specific names
from .discounts import apply_discount
from .tax import add_taxfrom shop.discounts import apply_discount
from shop.tax import add_tax
price = 1000
price = apply_discount(price, 10)
price = add_tax(price)
print(f"Final price: {price}")Final price: 945.0The dotted path shop.discounts tells Python exactly where to look: inside the shop package, for the discounts module.
Absolute Imports
An absolute import spells out the full path to a module, starting from the top-level package or project root. This is what you saw above, and it is the most common and most readable style.
from shop.discounts import apply_discount
from shop.tax import add_taxAbsolute imports make it immediately obvious where a function comes from, and they behave consistently whether the importing file is run directly or imported by something else. Most style guides, including PEP 8, recommend them.
Relative Imports
A relative import refers to a module's location relative to the current module, using dots. A single dot (.) means "the current package," and two dots (..) mean "one level up."
shop/
__init__.py
discounts.py
tax.py
receipts.pyfrom .discounts import apply_discount
from .tax import add_tax
def build_receipt(price):
price = apply_discount(price, 10)
price = add_tax(price)
return f"Total: {price}"Here, .discounts means "the discounts module inside this same package." Relative imports only work inside packages, and only when the file is imported as part of that package — not when run directly as a standalone script.
A file using relative imports cannot simply be run directly with python receipts.py — Python raises an error because there is no package context to resolve the dots from. It must be imported as part of the package (e.g., run via main.py, or with python -m shop.receipts).
Module vs Package vs Library vs Framework
These four terms are related but distinct, and it is easy to blur them together as a beginner.
Module
A single .py file containing Python code — functions, classes, or variables.
Package
A directory of related modules (with an __init__.py) grouped under one importable name.
Library
A collection of one or more packages/modules published for others to reuse (e.g., requests, NumPy). You call into a library from your own code.
Framework
A larger structure that provides the skeleton of an application and calls your code (e.g., Django, Flask). You build within a framework rather than just calling it.
You call a library; a framework calls you. A module is one file; a package is a folder of modules; a library or framework is typically made up of many packages working together.
Common Mistakes
- Forgetting __init__.py and being confused about why a folder isn't recognized as a package (in older Python versions or certain tools).
- Trying to run a file that uses relative imports directly as a script.
- Mixing absolute and relative imports inconsistently within the same package.
- Confusing "module," "package," "library," and "framework" when describing a project.
- Creating overly deep, unnecessary nested sub-packages for a small project.
Best Practices
- Group related modules into a package once a project grows beyond a few files.
- Prefer absolute imports for clarity, reserving relative imports for closely related modules within the same package.
- Keep __init__.py simple — either empty or used to expose a clean public interface.
- Give packages clear, lowercase, descriptive names.
- Use the correct terminology (module, package, library, framework) so your explanations and documentation stay precise.
Frequently Asked Questions
Do I always need an __init__.py file?
It is not strictly required in modern Python for basic imports to work, but including one (even empty) is standard practice and avoids ambiguity, especially with tools and older Python versions.
Can a package contain other packages?
Yes. A package can contain sub-packages, each with its own __init__.py, allowing you to model larger, layered project structures.
What is the real difference between a package and a library?
A package is a specific folder-based Python structure. A library is a broader term for published, reusable code that may consist of one or several packages.
Why did my relative import fail when I ran the file directly?
Relative imports need to know their position within a package. Running a file directly with python file.py strips that context. Run it through the package (e.g., via a main script, or python -m package.module) instead.
Is Django a package or a framework?
Django is a framework. Internally, it is built from many packages and modules, but as a whole it defines the structure your application code plugs into.
Key Takeaways
- A package is a directory of related modules, typically marked with an __init__.py file.
- Packages let you organize a growing project into clean, logical groups of code.
- Absolute imports spell out the full path; relative imports use dots relative to the current package.
- Relative imports only work when a file is imported as part of a package, not run directly.
- Module, package, library, and framework each describe a different scale of reusable code.
Summary
Packages give you a way to scale beyond single-file modules by grouping related code into directories that Python understands how to import. Absolute and relative imports each have their place, and knowing the difference avoids confusing import errors.
You also clarified the terminology that often confuses beginners: modules are files, packages are folders of modules, libraries are published reusable code, and frameworks provide the structure your code lives inside of.
- You understand what a package is and the role of __init__.py.
- You can organize a small project into a clean package structure.
- You can use both absolute and relative imports correctly.
- You can clearly distinguish modules, packages, libraries, and frameworks.