Since there are so many questions on relative imports, I will make it as short and sweet as possible. And yes, I've read "Relative imports for the billionth time".
I have a project structure like this:
.
├── Makefile
└── src
├── __init__.py
├── model
│ └── train_model.py
└── preprocessing
└── process.py
where I want to be able to, as an example, call make preprocessing
or make train
which then runs either process.py
or train_model.py
with
## Make train
train:
python3 src/model/train_model.py
E.g. modules will always from the top project folder where the Makefile lives.
Now, my problem is that i might have dependencies between different submodules, such as train_model.py
and process.py
. Specifically, if I try to import process
in train_model
by using from src.preprocessing import process
i get an error ImportError: No module named 'src'
. In a similar vein, I've tried from ...preprocessing import process
, which gives me another error: SystemError: Parent module '' not loaded, cannot perform relative import
.
I use if __name__ == '__main__':
at the end of my train_model.py
, but I can't seem to figure out, how python uses __name__
to find different modules, and if this f**** something up in the process.
Use PYTHONPATH
. I would do it this way:
Makefile:
export PYTHONPATH=$(abspath src)
train:
python3 src/model/train_model.py
train_model.py:
from preprocessing import process
Now every import will first look under src
. It is not conventional to write from src.preprocessing import process
- typically imports are understood to be within some base directory (you wouldn't want to set PYTHONPATH
to the directory above src
, because it may contain things you don't want to import).