18

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+?

Community
  • 1
  • 1
max
  • 49,282
  • 56
  • 208
  • 355
  • 1
    The only real reason I see, to keep using `__init__.py`, is for backwards compatibility. – Christian Dean Oct 19 '16 at 17:49
  • @leaf so what about the [example](http://stackoverflow.com/a/29509611/336527) I mentioned? What's a canonical way to do this in python 3.3+? – max Oct 19 '16 at 19:22

1 Answers1

6

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.

Community
  • 1
  • 1
Chris
  • 6,805
  • 3
  • 35
  • 50
  • 1
    Then, perhaps, it is best practice to avoid _packages_ whenever possible, and use _namespaces_ instead? Or is there some problem with that approach? – max Oct 26 '16 at 02:19
  • 1
    It seems the advantage of namespace is that they are extensible. Their disadvantage is that you can't have `__init__.py` in them and therefore can't do some things (like encapsulating the file structure, performing initialization, etc.). Does it sound right? – max Nov 21 '16 at 08:47