Yes, this file is required if you want directory to be treated as a module.
The
__init__.pyfiles are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case,__init__.pycan just be an empty file, but it can also execute initialization code for the package or set the__all__variable, described later.
https://docs.python.org/3/tutorial/modules.html#packages
In a __init__.py file you have great possibility to document module, to get rid of the nested imports for a user/developer by providing the most useful objects(classes/functions) at the first level… …actually to be as simple in use as possible.
Edit after question update
The default importer/finder (examine the sys.meta_path) is:
- BuiltinImporter – searches for/load a built-in module
- FrozenImporter – searches for/loads frozen module (e.g. *.pyc)
- PathFinder – the one you are interested in, allow to search for/loads a module based on the file system
The third is the __init__.py thing (actually the FrozenImporter as well).
ThePathFinder searches for a module in the paths from sys.path (and in __path__ defined in a package). The module could be either a standalone python file (if it is in the root of the search path) or a directory with __init__.py.
Referring to your example:
foo/
bar/
__init__.py
baz.py
-
If you create
__init__.pyinfoo/,foo.bar.bazwill be available (as you said). -
If you add
foo/tosys.pathor pass it throughPYTHONPATH=foo/,bar.bazwill be available (note without parent modulefoo). -
If you write your own finder (and loader) you can load for example any file you want despite where it is. That gives you great power. For example take a look on
stack-overflow-import, exposes code based on SO’s search results.