Python Packages
Learn how Python packages organize multiple modules into structured projects, how imports work across packages, and how professional Python applications manage dependencies.
Learning Objectives
In the previous lesson, you learned how individual Python files can be used as modules. Now we will take the next step: organizing multiple modules into packages.
- Understand what a Python package is.
- Understand the difference between modules and packages.
- Create your own package.
- Import modules from packages.
- Understand
__init__.py. - Use absolute and relative imports.
- Understand nested packages.
- Install third-party packages using pip.
- Understand
requirements.txt. - Understand how packages fit into professional projects.
What Is a Package?
A Python package is a way of organizing related Python modules into a directory structure.
If a module is like a single toolbox, a package can be thought of as an entire workshop containing several specialized toolboxes.
A module is usually a Python file, while a package organizes multiple modules and possibly subpackages into a larger structure.
Example
shop/
├── products.py
├── customers.py
├── payments.py
└── reports.py
The shop directory can serve as a package
containing several related modules.
Modules vs Packages
These two terms are closely related, but they represent different levels of organization.
calculator.py
A module is generally a single Python file containing functions, classes, variables, or other Python code.
shop/
├── products.py
├── customers.py
├── cart.py
└── payments.py
A package groups related modules together.
Function → Module → Package → Application
Why Packages Matter
Small Python programs can be managed with a few files. Professional applications, however, can contain hundreds or even thousands of modules.
Packages help developers organize these modules logically.
Benefits of packages
- Better project organization.
- Clear separation of responsibilities.
- Reusable code.
- Reduced naming conflicts.
- Easier maintenance.
- Better team collaboration.
- Scalable application structure.
application/
├── users/
├── products/
├── orders/
├── payments/
├── reports/
└── utilities/
Package Structure
A package is represented by a directory containing Python modules.
A traditional package commonly contains an
__init__.py file.
shop/
├── __init__.py
├── products.py
├── customers.py
└── orders.py
The files can contain different parts of the application's functionality.
Modern Python can also support namespace packages
without requiring an __init__.py file.
However, understanding __init__.py is
still important because it is widely used in
conventional Python packages.
__init__.py
The __init__.py file is a special Python file
traditionally used to mark a directory as a package.
It can also contain package-level initialization code or expose selected names from modules.
Example
print("Shop package loaded")
When the package is imported, this code may execute as part of package initialization.
Avoid putting large amounts of application logic
inside __init__.py. Keep initialization
simple and predictable.
Creating Your First Package
Let's create a small package for an e-commerce application.
Step 1 — Create the folder
shop/
Step 2 — Add package files
shop/
├── __init__.py
├── products.py
└── pricing.py
Step 3 — Create products.py
products = [
"Laptop",
"Keyboard",
"Mouse"
]
def product_count():
return len(products)
Step 4 — Create pricing.py
def apply_discount(price, rate):
return price - (price * rate)
Importing a Package
Once your package is created, you can import it from another Python file.
import shop
Importing the package itself does not automatically mean every module inside it can be accessed in the way you might expect. It is often clearer to explicitly import the module you need.
Importing a Module from a Package
Use dot notation to import a module inside a package.
import shop.products
print(shop.products.product_count())
3
Here, Python first identifies the shop package
and then accesses its products module.
from Package import Module
A common and readable approach is to import the specific module you need.
from shop import products
print(products.product_count())
You can also import specific functions.
from shop.pricing import apply_discount
price = apply_discount(1000, 0.10)
print(price)
900.0
Import Aliases
Packages and modules can also be given shorter aliases.
import shop.pricing as pricing
price = pricing.apply_discount(5000, 0.15)
print(price)
4250.0
Aliases are particularly useful when a module name is long or when a conventional short name improves readability.
Nested Packages
A package can contain another package. This is called a nested package or subpackage.
store/
├── __init__.py
├── products/
│ ├── __init__.py
│ ├── catalog.py
│ └── inventory.py
│
├── customers/
│ ├── __init__.py
│ └── profiles.py
│
└── payments/
├── __init__.py
└── checkout.py
This structure is useful when a project becomes large enough to require multiple logical sections.
Importing from a nested package
from store.products import catalog
Absolute Imports
An absolute import specifies the full path from the project's package structure.
from store.products import catalog
Absolute imports are often easier to understand because the source of the imported module is explicit.
Prefer clear imports that make the source of a dependency obvious.
Relative Imports
Relative imports refer to modules based on the current package location.
A single dot generally means the current package, while two dots refer to the parent package.
from . import pricing
Another example:
from ..utilities import helpers
Relative imports are mainly useful inside package structures. They can be confusing when beginners run individual files directly, so use them carefully.
Third-Party Packages
Python's standard library is powerful, but developers often need additional functionality.
Thousands of third-party packages are available through the Python ecosystem.
Examples
- NumPy — numerical computing
- Pandas — data analysis
- Requests — HTTP requests
- Matplotlib — data visualization
- Flask — web applications
- FastAPI — modern APIs
Packages allow developers to build sophisticated applications without reinventing every component themselves.
Installing Packages with pip
pip is the standard package-management tool
commonly used to install Python packages from the Python
Package Index and other package sources.
Installing a package
python -m pip install requests
After installation, your Python program can import the package.
import requests
response = requests.get("https://example.com")
print(response.status_code)
Installing packages directly into a global Python installation can create dependency conflicts. Virtual environments are generally preferred for projects.
requirements.txt
A Python project often needs a way to record its external dependencies.
One traditional approach is a file called
requirements.txt.
requests
numpy
pandas
matplotlib
Another developer can then install the listed dependencies using:
python -m pip install -r requirements.txt
Version pinning
Projects may specify package versions to make environments more predictable.
requests==2.32.3
numpy==2.1.3
Packages & Virtual Environments
Different projects may require different versions of the same package.
A virtual environment creates an isolated Python environment for a project.
python -m venv .venv
After creating the environment, you activate it according to your operating system and shell.
Once activated, packages installed with pip are associated with that environment rather than being mixed with every project on the computer.
A common Python workflow is:
- Create a virtual environment.
- Activate it.
- Install project dependencies.
- Develop and test the application.
- Record dependencies for reproducibility.
Real-World Project Structure
Let's look at how packages can be used in a realistic e-commerce application.
ecommerce_app/
│
├── main.py
├── requirements.txt
│
├── users/
│ ├── __init__.py
│ ├── models.py
│ ├── services.py
│ └── validation.py
│
├── products/
│ ├── __init__.py
│ ├── models.py
│ ├── catalog.py
│ └── inventory.py
│
├── orders/
│ ├── __init__.py
│ ├── models.py
│ ├── checkout.py
│ └── tracking.py
│
└── payments/
├── __init__.py
├── gateway.py
└── invoices.py
Each package represents a logical part of the application. Inside each package, modules handle more specific tasks.
Importing from this structure
from products.catalog import get_product
from orders.checkout import create_order
from payments.invoices import generate_invoice
The project is divided according to responsibility. This makes it easier for different developers to understand and maintain the application.
Common Mistakes
1. Confusing modules and packages
Remember: a module is typically a Python file; a package organizes modules into a directory structure.
2. Incorrect import path
Make sure your package and module names match the actual project structure.
3. Running files incorrectly
Relative imports depend on package context. Running an individual module as a standalone file can produce import problems.
4. Installing packages globally
Global installations can lead to dependency conflicts between projects. Prefer virtual environments for project work.
5. Overcomplicating the package structure
Packages should make a project easier to understand, not harder. Create structure according to actual responsibilities.
Organize code according to responsibility and keep dependencies explicit and understandable.
Practice Exercises
Try these exercises yourself. The goal is to build packages rather than simply reading about them.
Exercise 1 — Create a Package
Create a package called calculator with
modules for addition and subtraction.
Exercise 2 — Import a Module
Import your calculator module into main.py
and use one of its functions.
Exercise 3 — Create a Utility Package
Create a package called utilities containing
a text utility module and a number utility module.
Exercise 4 — Nested Package
Create a package called school containing
a nested package called students.
Exercise 5 — pip
Create a virtual environment and practice installing a
small third-party package using
python -m pip install.
Exercise 6 — Requirements
Create a requirements.txt file containing
the dependencies used by your practice project.
Mini Challenge — Build an E-commerce Package
Now combine what you learned about modules and packages. Build a small package structure for an online store.
Create a package called store that
contains separate modules for products, pricing,
and customers.
Suggested structure
store_project/
│
├── main.py
│
└── store/
├── __init__.py
├── products.py
├── pricing.py
└── customers.py
Requirements
-
Create a product list inside
products.py. - Create a function that returns the product count.
-
Create a discount function inside
pricing.py. -
Create a customer function inside
customers.py. -
Import these modules into
main.py. - Display a simple store report.
Example data
products = [
{"name": "Laptop", "price": 120000},
{"name": "Keyboard", "price": 5000},
{"name": "Mouse", "price": 2500}
]
Challenge goal
Your final program should import functionality from the package and display information such as:
Store Report
-------------
Products: 3
Customers: 25
Discount: 10%
Do not place everything inside
main.py. Decide which responsibility
belongs in which module.
Quick Knowledge Check
Test your understanding of Python packages.
1. What is a Python package?
2. What is a module?
3. What is __init__.py traditionally used for?
4. Which statement imports a module from a package?
5. What does as provide?
6. What is a nested package?
7. Which command installs a package with pip?
8. What is requirements.txt commonly used for?
9. Why are virtual environments useful?
10. Which is an example of a third-party package?
Lesson Summary
Packages allow Python developers to organize multiple related modules into structured and scalable applications.
-
A module is generally a Python
.pyfile. - A package organizes related modules.
-
__init__.pyis commonly used for package initialization. - Packages can contain subpackages.
- Modules can be imported using package paths.
- Absolute imports provide explicit paths.
- Relative imports refer to the current package structure.
- Third-party packages extend Python's capabilities.
-
pipis commonly used to install Python packages. -
requirements.txtcan record project dependencies. - Virtual environments isolate project packages.
- Good package organization makes large projects easier to maintain.
You now understand the two major building blocks of Python project organization: modules and packages.
In the next lesson, we will start working with files and learn how Python programs can read, write, append, and manage external data.
Ready for the Next Lesson?
Make sure you understand packages, imports,
__init__.py, pip, and project organization
before continuing.