No __init__.py, but still considered a package?

A foobar package

  • Foobar

    • __ init__.py
    • foo.py
    • bar

      • bar.py

Inside the __init__.py

 from . import foo from . import bar 

Even if bar not a package or subpackage, it is still imported as a module (lolwut). I checked the import type by doing print(type(bar)) inside __init__.py and typing <class 'module'> ... what it is. What's going on here? This is a module object, so I did print(dir(bar)) , and the result was ['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__'] . Now, even more confusing to me, this is the __path__ variable. Isn't that just a batch thing?

Is this what is called a name pack? I think this is not the case, however, I tried one more thing inside this __init__.py file - added the line import bar.bar . It ended with ImportError . So, to summarize my question, why is this module useful? Why did Python import this in the first place?

There is an amazing tutorial on this subject by David Bezley . I watched all this a while ago, but I think I should watch it again to remember everything.

+5
source share
1 answer

From documents

A module is a file containing Python definitions and statements . The file name is the name of the module with the suffix .py added. Inside the module, the module name (as a string) is available as the value of the __name__ global variable.

...

Packages are a way of structuring the Pythons module namespace using dashed module names. For example, module name AB denotes a submodule named B in a package named A.

...

Packages support another special __path__ attribute. This is initialized as a list containing the name of the directory in which the __init__.py packages are stored before the code in this file is executed. This variable can be changed; this affects subsequent searches for modules and subpackages contained in the package.

Although this feature is often not required, it can be used to expand the set of modules found in the package .

So yes, the __path__ variable also applies to modules inside the package, and these modules are considered as "submodules of the package"

Edit In Python 2.x, this package is from . import bar from . import bar will return ImportError on this line. In Python 3.x, modulefoobar.foo is of type <module 'foobar.foo' from '../py/foobar/foo.py'> and foobar.bar of <module 'foobar.bar' (namespace)> .

Apparently he appeared here.

Regular packages will continue to have init.py and will be in the same directory. Namespace packages cannot contain init.py

0
source

All Articles