I have a simple example project with these files:
folder
__init__.py
foo.py
foobar.py
script.py
In foobar.py the function foo
is imported with from .foo import foo
.
(It is then used in the function foobar
).
In script.py the function foobar
is imported with from .foobar import foobar
.
(It is then executed.)
But putting the dots in the import statement is not always the right choice.
Depending on how the script is run, their presence can cause:
ImportError: attempted relative import with no known parent package
Or their absence can cause:
ModuleNotFoundError: No module named 'foobar'
The code can be found on GitHub. (There is also the same with absolute paths.)
with dots
This works for the two usecases that I need:
- run script using the m-switch:
python -m project.folder.script
- import
foobar
in the Python console:from project.folder.foobar import foobar
This screenshot shows how running the script works with and fails without the m-switch:
without dots
Gladly there is no need to run the script without the m-switch.
(Although it would be nice, because the IDE has a button for that.)
This screenshot shows how running the script fails with and works without the m-switch:
paths in detail
It seems worthwhile to take a closer look at __name__
and __file__
in all cases.
__name__
of _script.py is always the string '__main__'
.
conclusion
Apparently for me this just boils down to having to use the dot and the m-switch.
(This is just mildly annoying, because my IDE does not have auto-completion for it.)
But I would still like to understand, why there are these two ways of doing essentially the same thing.
People often say, that the dot is for going up a directory (like ../
in HTML and PHP).
But there is something wrong with that, because the location is the same in both cases.
(We just talk about neighboring files in the same folder.)
This must be far from the first question about this topic.
I hope it is clear enough to compensate for that redundancy.