What is a Package in Python?
A package is a way of organizing related Python modules into a directory structure. Packages help developers divide large applications into smaller, reusable, and maintainable components.
A package can contain multiple modules and subpackages. Traditionally, an __init__.py file is used to identify a directory as a Python package. Modern Python also supports namespace packages that do not require it.
Package
A directory that organizes related Python modules and subpackages.
Module
A Python file containing reusable functions, classes, and variables.
__init__.py
A package initialization file commonly used to define package-level behavior or exports.
Subpackage
A package inside another package, useful for organizing larger applications.
Suppose we want to create a package called calculator.
project/
│
├── main.py
│
└── calculator/
├── __init__.py
├── addition.py
└── subtraction.pyHere, calculator is the package and addition.py and subtraction.py are modules inside it.
Create a folder named calculator and add an __init__.py file.
# Calculator package
print("Calculator package loaded")
The package can now contain additional modules such as addition.py and subtraction.py.
Create an addition module inside the calculator package.
def add(a, b):
return a + b
Create another module for subtraction.
def subtract(a, b):
return a - b
from calculator import addition
result = addition.add(20, 30)
print("Result:", result)
Result: 50
A specific function can be imported directly from a module inside a package.
from calculator.addition import add
result = add(100, 200)
print("Result:", result)
Result: 300
from calculator import addition
from calculator import subtraction
print(addition.add(20, 10))
print(subtraction.subtract(20, 10))
30
10
The __init__.py file can be used to expose selected functions at the package level.
from .addition import add
from .subtraction import subtract
Now the functions can be imported directly from the package.
from calculator import add, subtract
print(add(50, 20))
print(subtract(50, 20))
70
30
A banking application can be divided into separate modules such as accounts, transactions, and loans.
banking/ │ ├── __init__.py ├── account.py ├── transaction.py └── loan.py
class BankAccount:
def __init__(self, account_number, balance):
self.account_number = account_number
self.balance = balance
def deposit(self, amount):
self.balance += amount
return self.balance
def get_balance(self):
return self.balance
from banking.account import BankAccount
account = BankAccount(
"ACC1001",
10000
)
account.deposit(5000)
print("Account:", account.account_number)
print("Balance:", account.get_balance())
Account: ACC1001
Balance: 15000
An e-commerce application can organize product, order, payment, and customer functionality into packages and modules.
ecommerce/
│
├── __init__.py
│
├── products/
│ ├── __init__.py
│ └── product.py
│
├── orders/
│ ├── __init__.py
│ └── order.py
│
└── payments/
├── __init__.py
└── payment.pyclass Product:
def __init__(self, name, price):
self.name = name
self.price = price
def display(self):
print(self.name)
print(self.price)
from ecommerce.products.product import Product
product = Product(
"Laptop",
75000
)
product.display()
Laptop
75000
An HR system can separate employee, salary, attendance, and leave functionality.
hr/ │ ├── __init__.py ├── employee.py ├── salary.py ├── attendance.py └── leave.py
class Employee:
def __init__(self, name, employee_id):
self.name = name
self.employee_id = employee_id
def display(self):
print("Employee:", self.name)
print("ID:", self.employee_id)
def calculate_annual_salary(monthly_salary):
return monthly_salary * 12
def calculate_bonus(monthly_salary):
return monthly_salary * 0.10
from hr.employee import Employee
from hr.salary import calculate_bonus
employee = Employee(
"Priya",
"EMP101"
)
employee.display()
bonus = calculate_bonus(60000)
print("Bonus:", bonus)
Employee: Priya
ID: EMP101
Bonus: 6000.0
Payment applications can separate different payment methods into individual modules.
payment/ │ ├── __init__.py ├── card.py ├── upi.py └── netbanking.py
def pay_by_card(amount):
print("Processing card payment...")
print("Amount:", amount)
return "Card payment successful"
def pay_by_upi(amount):
print("Processing UPI payment...")
print("Amount:", amount)
return "UPI payment successful"
from payment.card import pay_by_card
message = pay_by_card(2500)
print(message)
Processing card payment...
Amount: 2500
Card payment successful
A package can contain another package. This is called a nested package or subpackage structure.
company/
│
├── __init__.py
│
├── hr/
│ ├── __init__.py
│ ├── employee.py
│ └── salary.py
│
└── finance/
├── __init__.py
├── invoice.py
└── payment.pyfrom company.hr.employee import Employee
from company.finance.invoice import create_invoice
employee = Employee(
"Rahul",
"EMP500"
)
employee.display()
create_invoice(5000)
Nested packages are especially useful for large applications with many functional areas.
One package can contain many modules, each responsible for a specific part of the application.
shopping/ │ ├── __init__.py ├── product.py ├── cart.py ├── order.py ├── customer.py └── payment.py
This structure makes it easier to maintain and test each component independently.
Package modules can also be imported using aliases.
import calculator.addition as add_module
result = add_module.add(25, 15)
print("Result:", result)
Result: 40
Package-level information can be defined in __init__.py.
company_name = "ABC Technologies"
version = "1.0"
import company
print("Company:", company.company_name)
print("Version:", company.version)
Company: ABC Technologies
Version: 1.0
A school application can separate students, teachers, courses, and fees into different modules.
school/ │ ├── __init__.py ├── student.py ├── teacher.py ├── course.py └── fees.py
class Student:
def __init__(self, name, roll_no):
self.name = name
self.roll_no = roll_no
def display(self):
print("Student:", self.name)
print("Roll No:", self.roll_no)
from school.student import Student
student = Student(
"Anita",
101
)
student.display()
Student: Anita
Roll No: 101
Python developers can install third-party packages using the pip package manager.
pip install requests
After installation, the package can be imported into a Python program.
import requests
response = requests.get(
"https://example.com"
)
print(response.status_code)
| Feature | Module | Package |
|---|---|---|
| Meaning | Python file containing code | Organized collection of modules |
| Typical Extension | .py | Directory |
| Contains | Functions, classes, variables | Modules and subpackages |
| Example | employee.py | hr/ |
| Purpose | Reuse code | Organize larger codebases |
| Concept | Meaning | Example |
|---|---|---|
| Module | A single Python file | calculator.py |
| Package | A structured collection of modules | ecommerce/ |
| Library | Reusable collection of code distributed for use | Requests |
A larger banking application can use several packages organized by responsibility.
banking_app/
│
├── main.py
│
├── accounts/
│ ├── __init__.py
│ ├── savings.py
│ └── current.py
│
├── transactions/
│ ├── __init__.py
│ ├── deposit.py
│ └── withdrawal.py
│
└── customers/
├── __init__.py
└── customer.pyclass SavingsAccount:
def __init__(self, account_number, balance):
self.account_number = account_number
self.balance = balance
def deposit(self, amount):
self.balance += amount
def display(self):
print("Account:", self.account_number)
print("Balance:", self.balance)
from accounts.savings import SavingsAccount
account = SavingsAccount(
"SAV1001",
25000
)
account.deposit(5000)
account.display()
Account: SAV1001
Balance: 30000
- Group related modules inside the same package.
- Give packages meaningful names.
- Keep package responsibilities clear.
- Use subpackages for large applications.
- Keep __init__.py simple when possible.
- Expose only the functionality that should be part of the package API.
- Avoid circular imports between modules and packages.
- Use consistent naming conventions.
- Document reusable packages.
- Use virtual environments when managing third-party dependencies.
The following structure demonstrates how a real e-commerce application can use packages to separate different responsibilities.
ecommerce_app/
│
├── main.py
│
├── products/
│ ├── __init__.py
│ └── product.py
│
├── customers/
│ ├── __init__.py
│ └── customer.py
│
├── orders/
│ ├── __init__.py
│ └── order.py
│
└── payments/
├── __init__.py
└── payment.pyclass Product:
def __init__(self, name, price):
self.name = name
self.price = price
def process_payment(amount):
print("Processing payment:", amount)
return True
from products.product import Product
from payments.payment import process_payment
product = Product(
"Laptop",
75000
)
print("Product:", product.name)
print("Price:", product.price)
if process_payment(product.price):
print("Order completed successfully")
Product: Laptop
Price: 75000
Processing payment: 75000
Order completed successfully
- Create a package directory.
- Add related modules to the package.
- Use __init__.py when appropriate.
- Import required modules or functions.
- Use the package functionality in the application.
| Rule | Explanation |
|---|---|
| Package | Organizes related Python modules. |
| Module | A Python file inside or outside a package. |
| __init__.py | Can initialize a package and expose package-level names. |
| Subpackage | A package contained inside another package. |
| from package.module import | Imports selected functionality. |
| pip | Installs packages distributed through Python's package ecosystem. |
| Virtual Environment | Provides an isolated environment for project dependencies. |