Search code examples
pythonpython-import

Importing python modules from root folder


I am using python 2.7 and have the following project structure

main-folder

    --folder1
        - script.py

    --folder2
        - scr.py

    -- abc.py
    -- util.py

I am trying to import abc.py into util.py using

from main-folder import abc

but I am not getting error as below

ImportError: No module named main-folder

I also tried to append the path to main-folder to the path using

sys.path.append(r'path/to main-folder/main-folder')

I also have init.py in main-folder , folder1 & folder2


Solution

  • I'll assume your package is not actually called main-folder because that's a syntax error.

    • sys.path / PYTHONPATH is where Python looks for modules, so adding a folder to sys.path means what's in it can be imported (as a top-level module), it doesn't make the folder itself importable
    • when you run a script as a Python file, Python adds that file's folder on the PYTHONPATH e.g. here if you run main-folder/folder1/script.py, main-folder/folder1 is what's on your PYTHONPATH, and that obviously can't access abc or utils no matter how you slice it
    • import <foo> or from <foo> import <bar> is an absolute import, it starts its search from the PYTHONPATH[0]
    • you can specify PYTHONPATH on the command line, e.g. PYTHONPATH=. python main-folder/folder1/script.py will also add whatever . is to your PYTHONPATH, which may be what you want?
    • within a pacakge (a directory with an __init__ and a bunch of submodules), it's probably better to use relative imports e.g. util should use from . import abc if they're supposed to be sibling submodules of the same package

    [0] that's not actually true for Python 2, as PEP 328 necessarily had to keep the old behaviour working but you probably want to assume it regardless, you can "opt out" of the old behaviour by using the __future__ stanza listed in the PEP