In Python, the __init__.py file serves as a marker that designates a directory as a package. This enables the directory and its contents to be imported using standard module import syntax. Beyond merely signaling package status, this special file can also control initialization logic, define public interfaces, and shape how submodules are exposed.
1. Declaring a Package
A directory without __init__.py is treated as a regular folder by Python. Including this file—even if empty—tells the interpreter that the directory should be recognized as a package, making its modules importable.
# Directory structure
mypkg/
__init__.py
utils.py
core.py
Now, modules inside mypkg can be imported:
import mypkg.utils
from mypkg.core import MyClass
2. Executing Initialization Code
Code placed directly in __init__.py runs the first time the package is importde. This is useful for setting up logging, loading configurations, or initializing shared resources.
# mypkg/__init__.py
print("Loading mypkg...")
VERSION = "1.0.0"
Running import mypkg will print the message and make mypkg.VERSION accessible.
3. Defining Public API with __all__
The __all__ list in __init__.py dictates what is imported when someone uses from package import *. This helps enforce a clean public interafce.
# mypkg/__init__.py
from .utils import helper
from .core import Processor
__all__ = ['Processor', 'helper']
Now, from mypkg import * brings in only Processor and helper, even if other internal modules exist.
4. Supporting Nested Packages
For hierarchical packages, every subdirectory intended as a subpackage must also contain its own __init__.py.
mypkg/
__init__.py
io/
__init__.py
file_reader.py
This allows imports like:
from mypkg.io.file_reader import FileReader
5. Exposing Convenience Functions
__init__.py can define or re-export functions at the package level, simplifying usage for end users.
# mypkg/__init__.py
from .core import run_engine
def start():
return run_engine()
Users can then call:
import mypkg
mypkg.start()
Practical Examples
Example: Auto-loading Submodules
# mypkg/__init__.py
from . import utils, core
print("All components loaded.")
Importing mypkg now automatically loads utils and core.
Example: Restricting Wildcard Imports
# mypkg/__init__.py
from .math_ops import add, multiply
from .internal import secret_func # not meant for public use
__all__ = ['add', 'multiply']
With from mypkg import *, only add and multiply are available; secret_func remains hidden.
Example: Package-Level Function
# mypkg/__init__.py
def greet():
print("Welcome to mypkg!")
Used as:
import mypkg
mypkg.greet() # Output: Welcome to mypkg!