我有一个结构如下的项目:
project
├── api
│ ├── __init__.py
│ └── api.py
├── instance
│ ├── __init__.py
│ └── config.py
├── package
│ ├── __init__.py
│ └── app.py
├── requirements.txt
└── tests
└── __init__.py
我正在尝试从config.py
调用package/app.py
文件,如下所示:
# package/app.py
from instance import config
# I've also tried
import instance.config
import ..instance.config
from ..instance import config
但是我总是收到以下错误:
Traceback (most recent call last):
File "/home/csymvoul/projects/project/package/app.py", line 1, in <module>
from instance import config
ModuleNotFoundError: No module named 'instance'
修改sys.path
不是我想要做的。我知道这个问题已经得到很好的回答,但是给出的答案对我没有用。
EDIT:将app.py
移动到根文件夹时,它可以正常工作。但是我需要将其放在package
文件夹下。
您可以将父目录添加到PYTHONPATH
,为此,可以在sys.path
中列出的“模块搜索路径”中使用OS依赖的路径。因此,您可以轻松添加父目录,如下所示:
import sys
sys.path.insert(0, '..')
from instance import config
请注意,前面的代码使用相对路径,因此您必须在相同位置启动文件,否则可能无法正常工作。要从任何地方启动,可以使用pathlib
模块。
from pathlib import Path
import sys
path = str(Path(Path(__file__).parent.absolute()).parent.absolute())
sys.path.insert(0, path)
from instance import config
但是,以前的方法比其他方法更能破解,为使事情正确,首先需要根据这篇非常详细的博客文章python packaging重塑项目结构,并执行以下操作:
安装软件包:
pip install -e .
(带点)命令然后只需使用from instance import config
在Python 3.3及更高版本中,您无需在子目录中就需要导入__init__.py
文件。如here所述,拥有它们实际上可能会引起误解,因为这会导致在每个包含初始化文件的文件夹中创建程序包名称空间。
通过删除所有这些__init__.py
文件,您可以在运行package
时将其导入名称空间app.py
(包括子目录)中,但这仍然不是我们想要的。
Python解释器仍然不知道如何到达您的instance
名称空间。为此,您可以使用PYTHONPATH
环境变量,包括config.py
父级的路径。您可以按照@RMPR答案sys.path
中的建议进行操作,也可以直接设置环境变量,例如:
PYTHONPATH=/home/csymvoul/projects/project python3 /home/csymvoul/projects/project/package/app.py
然后导入依赖项,例如from instance import config
。