Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

usage of __init__.py

Tags:

python

I use __init__.py to run checks when I do from myprojects.something import blabla.

Today I started using pyzmq and I wanted to see what's going on behind the scenes. So I browsed the code in github and I find (for me) some strange usage of __init__.py there that I cannot explain myself.

For example zmq/core/__init__.py. What's the point of adding in zmq.core.__all__ the __all__'s value of zmq.core.constants, zmq.core.error, zmq.core.message, etc.?

In zmq/__init__.py I see at the end

__all__ = ['get_includes'] + core.__all__

where get_includes is a function which basically returns a list with the directory of the module and the utils directory in the parent directory.

What's the point of that? What has __init.py__ achieved by doing that?

like image 606
Pablo Avatar asked Sep 20 '12 22:09

Pablo


People also ask

What is purpose of __ init __ py?

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.

What is __ init __ py give an example?

The __init__.py file makes Python treat directories containing it as modules. Furthermore, this is the first file to be loaded in a module, so you can use it to execute code that you want to run each time a module is loaded, or specify the submodules to be exported.

Do you still need __ init __ py?

Starting with Python 3.3, Implicit Namespace Packages were introduced. These allow for the creation of a package without any __init__.py file. Of course, it can still be present if package initialization is needed. But it is no longer required.

What is the purpose of __ init __ py file at the time of creating Python packages?

It provides an easy way for you to group large folders of many separate python scripts into a single importable module. If you remove the __init__.py file, Python will no longer look for submodules inside that directory, so attempts to import the module will fail.


1 Answers

The __all__ is for when someone does from module import * as documented here.

The only solution is for the package author to provide an explicit index of the package. The import statement uses the following convention: if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered. It is up to the package author to keep this list up-to-date when a new version of the package is released. Package authors may also decide not to support it, if they don’t see a use for importing * from their package. For example, the file sounds/effects/__init__.py could contain the following code:

__all__ = ["echo", "surround", "reverse"]

This would mean that from sound.effects import * would import the three named submodules of the sound package.

One use for __all__ is a tool for package builders to allow them to structure their package in a way that works for them while making it convenient for users. Specifically in the case of pyzmq, it lets you write code such as:

import zmq
print zmq.zmq_version()

Rather than having to use the full dotted module name:

print zmq.core.version.zmq_version()

The package designers of pyzmq are using __all__ to promote namespace elements from nested modules up to the top level of their namespace so the user isn't bothered by the structure of their package.

like image 136
John Gaines Jr. Avatar answered Sep 21 '22 12:09

John Gaines Jr.