Solving problem is about exposing yourself to as many situations as possible like What is __init__.py for? and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about What is __init__.py for?, which can be followed any time. Take easy to follow this discuss.
__init__.py for in a Python source directory?
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 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()
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.
There are 2 main reasons for
For convenience: the other users will not need to know your functions’ exact location in your package hierarchy.
your_package/ __init__.py file1.py file2.py ... fileN.py
# in __init__.py from file1 import * from file2 import * ... from fileN import *
# in file1.py def add(): pass
then others can call add() by
from your_package import add
without knowing file1, like
from your_package.file1 import add
If you want something to be initialized; for example, logging (which should be put in the top level):
import logging.config logging.config.dictConfig(Your_logging_config)
__init__.py file makes Python treat directories containing it as modules.
Furthermore, this is the first file to be loaded in a module, so you can use it to execute code that you want to run each time a module is loaded, or specify the submodules to be exported.
Since Python 3.3,
__init__.py is no longer required to define directories as importable Python packages.
Native support for package directories that don’t require
__init__.pymarker files and can automatically span multiple path segments (inspired by various third party approaches to namespace packages, as described in PEP 420)
Here’s the test:
$ mkdir -p /tmp/test_init $ touch /tmp/test_init/module.py /tmp/test_init/__init__.py $ tree -at /tmp/test_init /tmp/test_init ??? module.py ??? __init__.py $ python3 import sys sys.path.insert(0, '/tmp') from test_init import module import test_init.module $ rm -f /tmp/test_init/__init__.py $ tree -at /tmp/test_init /tmp/test_init ??? module.py $ python3 import sys sys.path.insert(0, '/tmp') from test_init import module import test_init.module
Although Python works without an
__init__.py file you should still include one.
It specifies that the directory should be treated as a package, so therefore include it (even if it is empty).
There is also a case where you may actually use an
Imagine you had the following file structure:
main_methods |- methods.py
methods.py contained this:
def foo(): return 'foo'
foo() you would need one of the following:
from main_methods.methods import foo # Call with foo() from main_methods import methods # Call with methods.foo() import main_methods.methods # Call with main_methods.methods.foo()
Maybe there you need (or want) to keep
main_methods (runtimes/dependencies for example) but you only want to import
If you changed the name of
__init__.py then you could use
foo() by just importing
import main_methods print(main_methods.foo()) # Prints 'foo'
This works because
__init__.py is treated as part of the package.
In Python the definition of package is very simple. Like Java the hierarchical structure and the directory structure are the same. But you have to have
__init__.py in a package. I will explain the
__init__.py file with the example below:
package_x/ |-- __init__.py |-- subPackage_a/ |------ __init__.py |------ module_m1.py |-- subPackage_b/ |------ __init__.py |------ module_n1.py |------ module_n2.py |------ module_n3.py
__init__.py can be empty, as long as it exists. It indicates that the directory should be regarded as a package. Of course,
__init__.py can also set the appropriate content.
If we add a function in module_n1:
def function_X(): print "function_X in module_n1" return
>>>from package_x.subPackage_b.module_n1 import function_X >>>function_X() function_X in module_n1
Then we followed the hierarchy package and called module_n1 the function. We can use
__init__.py in subPackage_b like this:
__all__ = ['module_n2', 'module_n3']
>>>from package_x.subPackage_b import * >>>module_n1.function_X() Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named module_n1
Hence using * importing, module package is subject to