Search code examples
pythonpython-importrelative-import

Properly doing relative imports in python


I always have the same problem and I finally want to get rid of it. My folder structure looks like this

project
├── scipts
│   └── folder
│       └── file.py
└── submodules
    └── lab_devices
        └── optical_devices
            └── __init__.py
            └── powermeter_driver.py

I now want to include the powermeter_driver.py in file.py. So what I do in the file.py is:

from submodules.lab_devices.optical_devices.powermeter_driver import PowermeterDriver

but this gives ModuleNotFoundError: No module named 'submodules'. I don't want to use

import sys
sys.path.insert(0, '../submodules')

Is there an easy workaround?


Solution

  • The imports will be resolved correctly if you run the script in the correct way, which is from the parent directory and using the -m switch. So you should cd in the parent folder, add __init__.py files as in:

    project
    ├── scripts
        └── __init__.py
    │   └── folder
            └── __init__.py
    │       └── file.py
    └── submodules
        └── __init__.py
        └── lab_devices
            └── __init__.py
            └── optical_devices
                └── __init__.py
                └── powermeter_driver.py
    

    so that python knows these are packages then run

    python -m scripts.folder.file # note no .py
    

    In file.py you can then use the absolute import as you are cause submodules will be detected as a package. You should indeed avoid hacking the sys.path by all means.