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").
Here's the documentation.
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__.py
file. When a regular package is imported, this__init__.py
file is implicitly executed, and the objects it defines are bound to names in the package’s namespace. The__init__.py
file 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
.
Is __init__.py not required for packages in Python 3.3+
Python 3.3+ has Implicit Namespace Packages that allow it to create a packages without an __init__.py
file.
Allowing implicit namespace packages means that the requirement to provide an
__init__.py
file can be dropped completely, and affected ... .
The old way with __init__.py
files still works as in Python 2.
What is the difference between __init__.py and __main__.py?
__init__.py is run when you import a package into a running python program. For instance, import idlelib
within a program, runs idlelib/__init__.py
, which does not do anything as its only purpose is to mark the idlelib directory as a package. On the otherhand, tkinter/__init__.py
contains most of the tkinter code and defines all the widget classes.
__main__.py is run as '__main__' when you run a package as the main program. For instance, python -m idlelib
at a command line runs idlelib/__main__.py
, which starts Idle. Similarly, python -m tkinter
runs tkinter/__main__.py
, which has this line:
from . import _test as main
In this context, .
is tkinter
, so importing .
imports tkinter
, which runs tkinter/__init__.py
. _test
is a function defined within that file. So calling main()
(next line) has the same effect as running python -m tkinter.__init__
at the command line.
Why do I need __init__.py at every level?
Yes, this file is required if you want directory to be treated as a module.
The
__init__.py
files 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__.py
can 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__.py
infoo/
,foo.bar.baz
will be available (as you said).If you add
foo/
tosys.path
or pass it throughPYTHONPATH=foo/
,bar.baz
will 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.
What's __name__ in the __init__.py?
__name__
is a "magic" variable within Python's module system. It's simply the module name, or what you import something as. For example, /radical/__init__.py
would mean that one could do the following
import radical
The __init__.py
is how you indicate to Python that you want a folder treated as a module. This allows module hierarchies to be built from multiple files, rather than one giant file. Take for example this piece of code: /radical/utils.py
import utils from radical
Without the __init__.py
Python treats it as an ordinary folder and so it won't have a module name.
If you run a script directly, __name__
is loaded as the __main__
module, which is why if __name__ == '__main__'
checks that you're running the file instead of importing it.
Is __init__.py required for every python package? [new feature since python 3.3+]
Python 3.3+ has implicit namespace packages that allow you to create packages without __init__.py
. In Python 2, __init__.py
is the old method and still works.
Allowing implicit namespace packages means that the requirement to provide an __init__.py file can be dropped completely, and affected portions can be installed into a common directory or split across multiple directories as distributions see fit.
Note: init.py files were used to mark directories on your disk as Python packages.
Useful links:
- Implicit Namespace Packages
using __init__.py
The vast majority of the __init__.py
files I write are empty, because many packages don't have anything to initialize.
One example in which I may want initialization is when at package-load time I want to read in a bunch of data once and for all (from files, a DB, or the web, say) -- in which case it's much nicer to put that reading in a private function in the package's __init__.py
rather than have a separate "initialization module" and redundantly import that module from every single real module in the package (uselessly repetitive and error-prone: that's obviously a case in which relying on the language's guarantee that the package's __init__.py
is loaded once before any module in the package is obviously much more Pythonic!).
For other concrete and authoritative expressions of opinion, look at the different approaches taken in the various packages that are part of Python's standard library.
How to use __init__.py in (sub-)modules to define namespaces?
Is this a good python-like way to define namespaces? Or is there a better / common way to organize the file-system of a package in python. (I did not find a proper tutorial/example for this.)
This is an okay way to setup a Python package. Only okay and not 'good' because of the contents of foo.py
and bar.py
.
I don't like to use
package.foo.foo()
/package.subpackage.bar.bar()
and would like to usepackage.foo()
/package.subpackage.bar()
.
In this case, you can't. And not mixing the name spaces is good reason to not do from package.subpackage.bar import bar
.
It would have been better if def foo(): ...
and def bar(): ...
were directly in __init__.py
. That way, you could have done package.foo()
and package.subpackage.bar()
. It could also have been done by using __all__
in init but import *
is also not considered good.
Or, the foo
and bar
packages should have had more in it like foo.function1
, foo.other_func
, bar.drink
, etc. which gives it more human-friendly understandable organisation.
Examples and references are not within scope for good StackOverflow questions but here are some, for a well thought-out question:
- Structuring Your Project — The Hitchhiker's Guide to Python
- The Pythonic way of organizing modules and packages
- How to organize a Python Project?
Related Topics
Convert Rgb Color to English Color Name, Like 'Green' With Python
What Do I Need to Read Microsoft Access Databases Using Python
Yes' Reporting Error With Subprocess Communicate()
Converting Epoch Time With Milliseconds to Datetime
Flatten an Irregular List of Lists
How to Check Whether a File Exists Without Exceptions
How to Add Sequential Counter Column on Groups Using Pandas Groupby
Why Do Backslashes Appear Twice
How to Terminate a Python Subprocess Launched With Shell=True
Process List on Linux Via Python
Django Server Killed Frequently
Integer Division by Negative Number
Webdriverwait Not Working as Expected
How to Make Function Decorators and Chain Them Together