The Problem:
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?
Caveats
- I'd like to avoid deleting the init files because they contain the
__all__parameter, and thats important for my program. - I'd also like to avoid writing more than one import statement in the main program, so the solution specified here wont work.
- I'm using Python 3.6
What I've Tried:
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?
Notes:
This issue seems to be described in the docs here