'How to import a module from a different folder?
I have a project which I want to structure like this:
myproject
├── api
│ ├── __init__.py
│ └── api.py
├── backend
│ ├── __init__.py
│ └── backend.py
├── models
│ ├── __init__.py
│ └── some_model.py
└── __init__.py
Now, I want to import the module some_model.py
in both api.py
and backend.py
. How do I properly do this?
I tried:
from models import some_model
but that fails with ModuleNotFoundError: No module named 'models'
.
I also tried:
from ..models import some_model
which gave me ValueError: attempted relative import beyond top-level package
.
What am I doing wrong here? How can I import a file from a different directory, which is not a subdirectory?
Solution 1:[1]
Firstly, this import statement:
from models import some_model
should be namespaced:
# in myproject/backend/backend.py or myproject/api/api.py
from myproject.models import some_model
Then you will need to get the directory which contains myproject
, let's call this /path/to/parent
, into the sys.path
list. You can do this temporarily by setting an environment variable:
export PYTHONPATH=/path/to/parent
Or, preferably, you can do it by writing a setup.py
file and installing your package. Follow the PyPA packaging guide. After you have written your setup.py
file, from within the same directory, execute this to setup the correct entries in sys.path
:
pip install --editable .
Solution 2:[2]
Unfortunately, Python will only find your file if your file is in the systems path. But fear not! There is a way around this!
Using python's sys
module, we can add a directory to the path just while Python is running, and once Python stops running, it will remove it from the path.
You can do this by:
import sys
sys.path.insert(0, '/path/to/application/app/folder')
import [file]
It is important to import sys and set the directory path before you import the file however.
Good luck!
Jordan.
Solution 3:[3]
I would lay out two approaches:
Simply import some_model
via absolute importing:
from myproject.models import some_model
Note that the myproject
should be treated as an module (i.e. having __init__.py
)
Or
You can add the previous path to the sys.path
which I use in such parallel level modules:
import sys
sys.path.append('../')
from models import some_model
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | sodimel |
Solution 2 | Jordan Mattiuzzo |
Solution 3 | Benyamin Jafari |