Now that __init__.py
is no longer required to make a directory recognized as a package, is it best practice to avoid them entirely if possible? Or are there still well-accepted use cases for __init__.py
in python 3.3+?
From what I understand, __init__.py
were very commonly used to run code at module import time (for example to encapsulate internal file structure of the package or to perform some initialization steps). Are these use cases still relevant with python 3.3+?
The __init__.py files are required to make Python treat directories containing the file as packages. This prevents directories with a common name, such as string , unintentionally hiding valid modules that occur later on the module search path.
__init__.py file is not needed from python version 3.3 and above !! All folders from python version 3.3 and above are considered a namespace package. All folders from python 3.3 and above having a __init__.py file are considers a standard package.
If a file named __init__.py is present in a package directory, it is invoked when the package or a module in the package is imported. You can use this to execute package initialization code, for example for the initialization of package-level data.
The __init__.py file lets the Python interpreter know that a directory contains code for a Python module. An __init__.py file can be blank. Without one, you cannot import modules from another folder into your project.
There's a very good discussion of this in this answer, and you should probably be familiar with PEP 420 to clarify the difference between and regular packages (use __init__.py
) and namespace packages (don't).
What I offer by way of answer is a combination of reading, references, and opinion. No claims to being "canonical" or "pythonic" here.
Are [initialization] use cases still relevant with python 3.3+?
Yes. Take your example as a use case, where the package author wants to bring several things into the root package namespace so the user doesn't have to concern themselves with its internal structure.
Another case is creating a hierarchy of modules. That reference (O'Reilly) actually says:
The purpose of the
__init__.py
files is to include optional initialization code that runs as different levels of a package are encountered.
They do consider namespace packages in that discussion, but continue:
All things being equal, include the
__init__.py
files if you’re just starting out with the creation of a new package.
So, for your second question,
is it best practice to avoid
__init__.py
entirely if possible?
No, unless your intent is to create a namespace package rather than a regular package, in which case you must not use __init__.py
.
Why might you want that? The O'Reilly reference has the clearest example I've seen about why namespace packages are cool, which is being able to collapse namespaces from separate, independently-maintained packages:
foo-package/
spam/
blah.py
bar-package/
spam/
grok.py
Which allows
>>> import sys
>>> sys.path.extend(['foo-package', 'bar-package'])
>>> import spam.blah
>>> import spam.grok
>>>
So anyone can extend the namespace with their own code. Cool.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With