Reputation: 1904
Supposing I have a directory structure like:
root/
__init__.py
foo.py
dir1/
__init__.py
bar.py
dir2/
__init__.py
baz.py
where the various python files contain some function called hello_world
.
What I want to be able to do is write something like:
import root
root.dir1.foo.hello_world()
root.dir1.dir2.baz.hello_world()
Of course, when I do this, I get a AttributeError: module has no attribute
error. This, I think, is due to the "the __init__.py trap" in the docs. How do I manipulate the init files such that I can make the above code run?
__all__
parameter, and thats important for my program. I've tried to get around this by changing the __init__.py files into namespace packages). Unfortunately, this doesn't seem to work. E.g. adding:
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
to the various init files doesn't change anything. Similarly, setting the __path__
attribute directly doesn't solve the problem. E.g. in each init file setting __path__ = ['<string name of child dir>']
doesn't resolve the error.
This is a bit mysterious to me, since the __path__
is supposed to tell python where to look for submodules, and the init files are supposed to be run sequentially, so why cant it figure out where things are?
This issue seems to be described in the docs here
Upvotes: 1
Views: 75
Reputation: 1904
One solution was to put a from . import *
after defining the __all__
property in each init file. E.g. in the init in dir1 put:
__all__ = ['foo', 'dir2']
from . import *
This solves the use case, but it seems like the wrong way. Open for better answers.
Upvotes: 1