I have a python package of the form:
package
├── __init__.py
├── module_1.py
└── module_2.py
Inside __init__.py I have:
__all__ = ["module_1", "module_2"]
Module_1 is:
__all__ = ["foo"]
def foo(): pass
Module_2 is:
__all__ = ["Bar"]
class Bar: pass
From the documentation I thought that the following code would import foo
and Bar
:
import package as pk
However, when I run pk.foo()
it throws an error: AttributeError: module 'package' has no attribute 'foo'
(same for Bar).
Thanks to this answer, I know that to get the desired behavior, I can change __init__.py into:
from .module_1 import *
from .module_2 import *
The above works.
However, I do not understand the documentation. The lines:
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
Sound like my original __init__.py should have worked (the one with __all__ = ["module_1", "module_2"]
). That is, the line import package as pk
should have imported the modules module_1
and module_2
, which in turn make foo
and Bar
available.
What am I missing?
EDIT:
I have also tried using exactly what the documentation mentions. That is, using from package import *
, and then tried with package.foo()
and foo()
, but neither worked.
The first, package.foo()
, throws the error NameError: 'package' is not defined.
. The second, foo()
, throws the error NameError: 'foo' is not defined.
.
How would a working example look like?.. One where __init__.py is of the form __all__ = ["module_1", "module_2"].