I'm baffled by the importing dynamics in __init__.py
.
Say I have this structure:
package
├── __init__.py
└── subpackage
├── __init__.py
└── dostuff.py
I would like to import things in dostuff.py
. I could do it like this: from package.subpackage.dostuff import thefunction
, but I would like to remove the subpackage
level in the import statement, so it would look like this:
from package.dostuff import thefunction
I tried putting this in package/__init__.py
:
from .subpackage import dostuff
And what I don't understand is this:
# doing this works:
from package import dostuff
dostuff.thefunction()
# but this doesn't work:
from package.dostuff import thefunction
# ModuleNotFoundError: No module named 'package.dostuff'
Why is that, and how can I make from package.dostuff import thefunction
work?
The only way I see to make what you intend would be to actually create a package/dostuff.py
module and import all you need in it as from .subpackage.dostuff import thefunction
.
The point is that when you use from .subpackage import dostuff
in package/__init__.py
, you do not rename the original module.
To be more explicit, here is an example of use with both your import and a package/dostuff.py
file:
# We import the dostuff link from package
>>> from package import dostuff
>>> dostuff
<module 'package.subpackage.dostuff' from '/tmp/test/package/subpackage/dostuff.py'>
# We use our custom package.dostuff
>>> from package.dostuff import thefunction
>>> package.dostuff
<module 'package.dostuff' from '/tmp/test/package/dostuff.py'>
>>> from package import dostuff
>>> dostuff
<module 'package.dostuff' from '/tmp/test/package/dostuff.py'>
# The loaded function is the same
>>> dostuff.thefunction
<function thefunction at 0x7f95403d2730>
>>> package.dostuff.thefunction
<function thefunction at 0x7f95403d2730>
from X import Y
only works when X is an actual module path.
Y on the contrary can be any item imported in this module.
This also applies to packages with anything being declared in their __init__.py
. Here you declare the module package.subpackage.dostuff
in package
, hence you can import it and use it.
But if you try to use the module for a direct import, it has to exist on the filesystem
I hope that makes it clearer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With