Reputation: 824
I am struggling with nested __init__.py
in a Python package I am writting. The Package has the following architecture:
module/
├── __init__.py
├── submodule1
│ ├── __init__.py
│ └── source.py
└── submodule2
├── __init__.py
├── source.py
└── subsubmodule2
├── __init__.py
└── source.py
My intent is to be able to access functions defined in submodule2/source.py
through module.submodule2.function
and in subsubmodules2/source.py
through module.submodule2.subsubmodule2.function
.
The first thing I tried was to define __init__.py
in submodule2
this way:
from .subsubmodule2 import *
But doing so, I get the functions defined in subsubmodules2/source.py
through module.submodule2.function
(and module.function
).
If I do:
from . import subsubmodule2
I get these functions through module.subsubmodule2.function
.
I also tried to define __all__
keyword in __init__
, with no more success. If I understand well Python documentation, I guess I could leave empty __init__.py
files and it could work, but from my understanding that is not the best practice either.
What would be the best way to access these functions as intended in my module?
Upvotes: 6
Views: 4854
Reputation: 11238
in module
__init__.py
file write the module which you want to import as
from . import submodule1
from . import submodule2
__all__ = ['submodule1', 'submodule2']
Now, in submodule1 __init__.py
file write
from . import source
from . import subsubmodule
# if you want to import functions from source then import them or in source.py
# define __all__ and add function which you want to expose
__all__ = ['source', 'subsubmodule']
now in subsubmodule __init__
file define function or class which you want to expose
from . source import *
__all__ = ['source']
# if you want to use * as import, i suggest you to use __all__ in source.py and mention all exposed function there
Upvotes: 2
Reputation: 50126
The __init__.py
file represents its respective package. For example, module/submodule2/__init__.py
represents module. submodule2
.
In order to pull objects defined in submodules into their package namespace, import them:
# module/submodule2/__init__.py
from .source import *
Since __init__.py
is a regular Python module, one can also forgo a separate .source
module and define objects directly inside __init__.py
:
# module/submodule2/__init__.py
def function():
...
Note that subpackages themselves are already available as their respective name. One does not have to – and in fact should not – import them in the parent module. They will be imported if code using the package imports them.
Upvotes: 2