简体   繁体   中英

Python, absolute/relative import not working as expected

I apologize for the millionth post about this topic. I thought I had a good grip of the whole absolute/relative import mechanism - I even replied to a couple of questions about it myself - but I'm having a problem with it and I can't figure out how to solve it.

I'm using Python 3.8.0, this is my directory structure:

project_folder
    scripts/
        main.py
    models/
        __init__.py
        subfolder00/
            subfolder01/
                some_script.py --> contains def for some_function

I need to import some_function from some_script.py when running main.py, so I tried:

1) relative import

# in main.py

from ..models.subfolder00.subfolder01.somescript import some_function

but when I run (from the scripts/ folder)

python main.py

this fails with error:

ImportError: attempted relative import with no known parent package

This was expected, because I'm running main.py directly as a script, so its _ name _ is set to _ main _ and relative imports are bound to fail.
However, I was expecting it to work when running (always from within the scripts folder):

python -m main

but I'm getting always the same error.

2) absolute import

I tried changing the import in main.py to:

# in main.py

from models.subfolder00.subfolder01.somescript import some_function

and running, this time from the main project folder:

python scripts/main.py

so that - I was assuming - the starting point for the absolute import would be the project folder itself, from which it could get to models/....

But now I'm getting the error:

ModuleNotFoundError: No module named 'models'

Why didn't it work when using the -m option in the case of relative import, and it's not working when using absolute ones either? Which is the correct way to do this?

I think quite likely you missed python's official doc ( that even come offline ) https://docs.python.org/3/tutorial/modules.html

you'll need a dummy __init__.py within your module, at same level of some_script.py

I think your "absolute" import may not have been absolute in the truest sense.

Prior to running the python scripts/main.py command, you would have needed to setup PYTHONPATH environment variable to include the path to project_folder .

Alternatively I do something like this in main.py :

import sys
import os
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)),'..','models','subfolder00','subfolder01'))
from somescript import some_function

Maybe it is a little pedantic, but it makes sense to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM