https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html
In addition to labeling a directory as a Python package and defining __all__
, __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.
An example
Here is an example from one of my projects, in which I frequently import a sessionmaker called Session to interact with my database. I wrote a "database" package with a few modules:
database/ __init__.py schema.py insertions.py queries.py
My __init__.py
contains the following code:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = 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 Session
session = 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 Session
session = Session()`
Further reading
There is a pretty interesting reddit thread covering appropriate uses of` __init__.py `here:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
The majority opinion seems to be that` __init__.py` files should be very thin to avoid violating the "explicit is better than implicit" philosophy.