What is __init__.py for?
It used to be a required part of a package (old, pre-3.3 "regular package", not newer 3.3+ "namespace package").
Python defines two types of packages, regular packages and namespace packages. Regular packages are traditional packages as they existed in Python 3.2 and earlier. A regular package is typically implemented as a directory containing an
__init__.pyfile. When a regular package is imported, this
__init__.pyfile is implicitly executed, and the objects it defines are bound to names in the package’s namespace. The
__init__.pyfile can contain the same Python code that any other module can contain, and Python will add some additional attributes to the module when it is imported.
But just click the link, it contains an example, more information, and an explanation of namespace packages, the kind of packages without
__init__.py are used to mark directories on disk as Python package directories.If you have the files
mydir is on your path, you can import the code in
from spam import module
If you remove the
__init__.py file, Python will no longer look for submodules inside that directory, so attempts to import the module will fail.
__init__.py file is usually empty, but can be used to export selected portions of the package under more convenient name, hold convenience functions, etc.Given the example above, the contents of the init module can be accessed as
based on this
In addition to labeling a directory as a Python package and defining
__init__.py allows you to define any variable at the package level. Doing so is often convenient if a package defines something that will be imported frequently, in an API-like fashion. This pattern promotes adherence to the Pythonic "flat is better than nested" philosophy.
Here is an example from one of my projects, in which I frequently import a
Session to interact with my database. I wrote a "database" package with a few modules:
database/ __init__.py schema.py insertions.py queries.py
__init__.py contains the following code:
import osfrom sqlalchemy.orm import sessionmakerfrom sqlalchemy import create_engineengine = create_engine(os.environ['DATABASE_URL'])Session = sessionmaker(bind=engine)
Since I define
Session here, I can start a new session using the syntax below. This code would be the same executed from inside or outside of the "database" package directory.
from database import Sessionsession = Session()
Of course, this is a small convenience -- the alternative would be to define
Session in a new file like "create_session.py" in my database package, and start new sessions using:
from database.create_session import Sessionsession = Session()
There is a pretty interesting reddit thread covering appropriate uses of
The majority opinion seems to be that
__init__.py files should be very thin to avoid violating the "explicit is better than implicit" philosophy.