Relative and absolute imports in Python3
This always confuses me. When can I use relative imports (from ..module.misc import foo
)?
When do I have do use python -m foo
? I do not like doing that.
These two SO answers are very helpful:
The crux is that relative imports are not allowed in the main module (code that you run from the command line without the -m
switch, which I call “scripts”). I prefer running scripts from the root of the project directory, like python scripts/script1.py
.
There are two possible solutions.
- Organize all your importable content in subdirectories under your scripts directory.
scripts/ scripts/script1.py scripts/script2.py scripts/module1/__init__.py scripts/module1/foo.py ... scripts/moduleN/__init__.py scripts/moduleN/bar.py
Then in
scripts/script1.py
you can dofrom module1 import foo
, and runpython scripts/script1.py
. - If you need to have sibling directories like
base/ base/scripts/script1.py base/scripts/script2.py base/module1/__init__.py base/module1/foo.py ... base/moduleN/__init__.py base/moduleN/bar.py
then you need an
init_paths.py
inscripts
, containingimport sys; sys.path.append('.')
. Note the.
, not..
. This is because I intend to run scripts frombase
likepython scripts/script1.py
. Soscripts
is already in Python’ssys.path
, and theappend()
statement putsbase
in there too. Then, addimport init_paths.py
at the start of every script inscripts
. After that, you can import likefrom module1 import foo
. - Run with
python -m
. I do not consider this as an option because I dislike it.