4

Based on the the documentation for Packaging Python Projects, __init__.py should be empty. I want to know why? because I'm placing certain objects in the __init__.py file that are used in every module in the Package. On checking bunch of __init.py__ files in my local environments for standard packages like importlib, multiprocessing etc. All of them have a bunch of code in the file.

2
  • 3
    It should be empty for that simple example project. This does not apply to other projects, just like the part about def add_one(number): return number + 1 doesn't apply to all projects. Commented Jun 17, 2021 at 7:31
  • I just checked the link and it looks like they fixed the page to make it clearer. It now says: "__init__.py is recommended to import the directory as a regular package, even if as is our case for this tutorial that file is empty [1]." ... and the footnote talks about 'namespace packages' like many of the answers here.
    – Rhubarb
    Commented May 16 at 19:23

4 Answers 4

7

The sole purpose of __init__.py is to indicate that the folder containing this file is a package, and to treat this folder as package, that's why it is recommended to leave it empty.

Consider following hierarchy:

foo
    __init__.py
    bar.py

When you use from foo import bar or import foo.bar, Python interpreter will look for __init__.py in foo folder, if it finds it, the bar module will be imported else it won't; however, this behavior has changed over the time, and it may be able to successfully import the modules/packages even if __init__.py is missing, but remember Zen of Python: Explicit is better than implicit, so it's always safe to have it.

But in case, if you need some package level variables to be defined, you can do it inside the __init__.py file, and all the modules inside the package will be able to use it.

And in fact, if you look at PEP 257, it mentions that the __init__.py can also contain the documentation for package level information.

1
  • Exactly, If we think about Zen here, telling the reader init should be empty for me meant it should always be empty. I think it could be written in a better way. As you can see there are conflicting answers within this thread.
    – pyeR_biz
    Commented Jun 17, 2021 at 7:55
3

You're taking that statement as more general than it's meant. You're reading a statement from a tutorial, where they walk you through creating a simple example project. That particular example project's __init__.py should be empty, simply because the example doesn't need to do anything in __init__.py.

Most projects' __init__.py files will not be empty. Taking a few examples from popular packages, such as numpy, requests, flask, sortedcontainers, or the stdlib asyncio, none of these example __init__.py files are empty. They may perform package initialization, import things from submodules into the main package namespace, or include metadata like __all__, __version__, or a package docstring. The example project is just simplified to the point where it doesn't have any of that.

1
  • That's what I thought too, but I believe its not clear enough in the tutorial text and can cause confusion.
    – pyeR_biz
    Commented Jun 17, 2021 at 7:58
1

To my knowledge, there are three things you need to be aware of when you create a non-empty __init__ file:

  • it might be more difficult to follow the code. If you instantiate a = B() in __init__ it's even worse. I know developers who don't like it only for this reason
  • on package import contents of __init__ are evaluated. Sometimes it might be computation heavy or simply not needed.
  • namespace conflicts. You can't really instantiate bar in init and have a bar.py file in your package.

I like importing package contents in __init__ as otherwise in bigger projects import statements become ugly. Overall it's not a good or bad practice. This advice applies only to the project in this particular example.

-1

In some case, you didn't have any shared component in your package. Suppose Defining a little package for calculating some algorithms, Then you didn't need any shared component in your __init__

Not the answer you're looking for? Browse other questions tagged or ask your own question.