📦 Python Packages Guide
Beginner-friendly documentation about Python packages, imports, modules, and project organization.
This document explains:
- what packages are
- how imports work
- __init__.py
- package organization
- absolute vs relative imports
- common beginner mistakes
- project structure examples
📚 Table of Contents
- 📖 What is a Package?
- 📦 What is a Module?
- 🧱 Basic Package Structure
- 📥 Importing Modules
- 📌 init.py
- 🌿 Absolute Imports
- 🔗 Relative Imports
- 🛠️ Organizing Large Projects
- 📌 init.py Contents
- ⚠️ Common Beginner Mistakes
- 📚 Final Notes
📖 What is a Package?
A package is a folder containing Python modules.
Packages help: - organize code - separate logic - structure large projects - improve readability
📦 What is a Module?
A module is simply:
a Python file
Example:
utils.py
This file itself is a module.
🧱 Basic Package Structure
project/
│
├── main.py
├── parser/
│ ├── __init__.py
│ ├── config_parser.py
│ └── validator.py
│
└── render/
├── __init__.py
└── draw.py
📥 Importing Modules
Import Entire Module
import math
Usage:
math.sqrt(25)
Import Specific Function
from math import sqrt
Usage:
sqrt(25)
📌 init.py
__init__.py tells Python that a folder should behave like a package.
Without it, imports may fail in some project structures.
🌿 Absolute Imports
Absolute imports start from the project root.
Example
from parser.config_parser import parse_config
🔗 Relative Imports
Relative imports use dots (.).
Example
from .validator import validate_config
🛠️ Organizing Large Projects
Example organization:
project/
│
├── core/
├── parsing/
├── render/
├── utils/
├── tests/
└── assets/
└── main.py
And each folder would have a init.py file to make it a package.
📌 init.py Contents
In many Python projects, __init__.py is often left empty.
Example:
# __init__.py
This is completely normal and commonly used only to mark the folder as a package.
Why Leave It Empty?
An empty __init__.py:
- keeps the package simple
- avoids unnecessary imports
- helps Python recognize the directory as a package
What Can Be Inside init.py?
Although often empty, it may also contain: - package imports - helper variables - package initialization code - exposed public functions/classes
Example
from .config_parser import parse_config
from .validator import validate_config
This allows imports like:
from parser import parse_config
instead of:
from parser.config_parser import parse_config
Why This is Useful
This can: - simplify imports - expose public APIs - improve package organization
Very common in: - libraries - frameworks - large Python projects
Good Practice
For beginner projects:
- keeping __init__.py empty is completely fine
As projects grow larger: - it may be used to organize package exports and initialization logic
⚠️ Common Beginner Mistakes
❌ Missing init.py
Problem:
ModuleNotFoundError
❌ Circular Imports
Example:
# a.py imports b.py
# b.py imports a.py
❌ Running Files Directly
Bad:
python3 parser/config_parser.py
Better:
python3 main.py
📚 Final Notes
Understanding packages is extremely important for modern Python development.
Good package organization helps: - readability - maintainability - debugging - scalability - teamwork