我为关于这个话题的第100万篇帖子道歉。我认为我已经很好地掌握了整个绝对/相对导入机制——我甚至自己回答了一些关于它的问题——但是我遇到了一个问题,我不知道如何解决它。
我使用的是Python 3.8.0,这是我的目录结构:
project_folder
scripts/
main.py
models/
__init__.py
subfolder00/
subfolder01/
some_script.py --> contains def for some_function
我需要在运行main.py时从some_script.py导入some_function,所以我尝试:
1)相对导入
# in main.py
from ..models.subfolder00.subfolder01.somescript import some_function
但是当我运行(从脚本/文件夹)
python main.py
ImportError: attempted relative import with no known parent package
这是预料之中的,因为我直接将main.py作为脚本运行,所以它的_名称_被设置为_main_,相对导入必然会失败。
然而,我希望它在运行时工作(总是从脚本文件夹内):
python -m main
但是我总是得到相同的错误。
2)绝对导入
我尝试将main.py中的导入更改为:
# in main.py
from models.subfolder00.subfolder01.somescript import some_function
和运行,这一次从主项目文件夹:
python scripts/main.py
所以-我假设-绝对导入的起点将是项目文件夹本身,它可以从模型/....
但是现在我得到错误:
ModuleNotFoundError: No module named 'models'
为什么在相对导入的情况下使用-m选项不起作用,而在使用绝对导入的情况下也不起作用?哪一种方法是正确的?
我想你很可能错过了python的官方文档(甚至离线)https://docs.python.org/3/tutorial/modules.html
你将需要一个虚拟的__init__.py
在你的模块,在同一级别的some_script.py
我认为你的"绝对";Import在真正意义上可能不是绝对的。
在运行python scripts/main.py
命令之前,您需要设置PYTHONPATH
环境变量以包含project_folder
的路径。
或者我在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
这可能有点迂腐,但对我来说是有意义的。