Loading Page Content...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
When software grows beyond a handful of independent scripts, grouping related modules into organized directory hierarchies becomes essential. In Python, a directory structured to contain multiple modules and sub-packages is called a Package.
The cornerstone of traditional Python package architecture is the special file named __init__.py. In this lesson, you will master package structuring, design clean API facades that hide internal plumbing, leverage __all__ to govern exports, and understand the difference between relative and absolute imports.
Imagine walking into a massive shopping hypermarket like Reliance Retail or Big Bazaar:
+-------------------------------------------------------------------------+ | HYPERMARKET RECEPTION DESK ANALOGY | +-------------------------------------------------------------------------+ | | | Customer Enters Building: | | ──> Greeted immediately by the Ground Floor Reception (__init__.py) | | | | Without Reception (__init__.py Facade): | | ──> Customer is forced to wander through basement boiler rooms, | | internal loading docks, and electrical shafts: | | from store.internal.storage.baskets.items import buy_milk | | | | With Clean Reception Desk (__init__.py): | | ──> Receptionist neatly curates the catalog at the main lobby: | | __init__.py imports: from .groceries import buy_milk | | ──> Customer simply asks: | | from store import buy_milk (Clean, direct, and pleasant!) | | | +-------------------------------------------------------------------------+
__init__.py acts as the front desk receptionist: it initializes the package when imported and presents a curated public interface so external users don't have to know your internal file layout.
__init__.pyWhile Python 3.3+ supports "Namespace Packages" without __init__.py, regular packages require __init__.py to execute initialization code and support relative imports.
Any Python code written inside __init__.py executes automatically the first time the package is imported.
Instead of forcing users to write: from ecommerce_suite.payments.upi import process_upi_payment You can re-export the function in ecommerce_suite/__init__.py: from .payments.upi import process_upi_payment Allowing users to simply write: from ecommerce_suite import process_upi_payment
Python supports two distinct ways to import between modules inside a package:
+------------------------------------+------------------------------------+ | Absolute Import | Explicit Relative Import | +------------------------------------+------------------------------------+ | from ecommerce_suite.orders | from .orders import place_order | | import place_order | from ..payments import upi | | | | | Starts from project root | Uses dots to indicate hierarchy: | | Always unambiguous and clear | . -> Current directory | | | .. -> Parent directory | +------------------------------------+------------------------------------+
python -m package.submodule). Running a submodule directly (python package/submodule.py) breaks relative imports with ImportError: attempted relative import with no known parent package.__all__When someone writes from my_package import *, Python by default imports all names that don't start with an underscore. You can strictly govern which functions are public by defining the __all__ list in __init__.py:
Let us construct an architectural package simulation:
Client script consuming the package facade:
Expected Output:
Packages possess special attributes that provide structural insights:
Expected Output:
| Practice | Bad Implementation | Recommended Gold Standard |
|---|---|---|
| API Usability | Forcing users to import from deep nested files | Re-export key functions in __init__.py as a facade |
| Wildcard Safety | Leaving __all__ undefined in __init__.py | Explicitly define __all__ = [...] for public symbols |
| Relative Imports | Using relative imports inside top-level scripts | Use relative imports only inside package submodules |
| Circular Imports | Cross-importing sibling submodules in __init__ | Keep __init__.py lightweight; import on demand |
| Execution | Running submodules directly (python pkg/mod.py) | Run package modules using -m flag: python -m pkg.mod |
__init__.py file.__init__.py Role: Executes upon package import; used for package setup, version stamping (__version__), and facade re-exports.from .submodule import feature inside __init__.py flattens the user-facing import path.__all__ List: A list of strings defining what symbols are imported when from package import * is called.. denotes current directory package, .. denotes parent directory package.Architect a clean package structure for an Indian express courier company (e.g. BlueDart / Delhivery):
courier.py: Contains estimate_delivery_time(origin_pincode, dest_pincode)rates.py: Contains calculate_shipping_rate(weight_kg, is_express=False)__init__.py, construct a Facade:__all__ = ["estimate_delivery_time", "calculate_shipping_rate"].__version__ = "1.0.0".In the next lesson, we will continue your intermediate Python journey with Popular Python Modules Overview (3: Modules and Packages).
👉 Continue to Next Lesson: Popular Python Modules Overview →
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
| Previous Lesson | Next Lesson |
|---|---|
| Using __name__ == '__main__' | Popular Python Modules Overview |
Test your understanding of this lesson with 5 questions. Each question has one correct answer.