我正在尝试从父目录中的文件夹导入模型。我使用sys.path.append()。我的项目结构:
项目
- folder1
- file1.py
- …
- folder2
- file2.py
- …
在file1.py文件中:
sys.path.append('../Project')
from Project.folder2 import file2
然后得到:
ModuleNotFoundError: No module named Project
我知道还有其他方法,但这似乎是最简单的。我不确定我是否需要把绝对路径放到项目文件夹,但我希望不是因为我将在不同的计算机上运行这个项目(diff abs路径)。
你的代码中有2个错误:
Project
目录不只是上一级。从file1.py
的角度来看,它实际上是2级以上。看到这个:
$ cd ..
(venv) nponcian 1$ tree
.
└── Project
├── folder1
│ └── file1.py
└── folder2
└── file2.py
(venv) nponcian 1$ cd Project/folder1/
(venv) nponcian folder1$ ls ..
folder1 folder2
(venv) nponcian folder1$ ls ../..
Project
- 即使上面的工作,添加一个相对路径作为一个字符串将字面上附加该字符串作为其原始值。所以如果你添加一个
print(sys.path)
,它会显示如下内容:
['/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '../Project', '.']
- 它实际上添加了
'../Project'
,所以如果python开始在文件夹2中搜索目标模块,它仍然不会找到它们,因为它如何知道'../Project'
相对于哪里。
解决方案您需要添加的是绝对路径。如果你的问题是它可能会改变,那也没关系,因为我们不需要固定的绝对路径。我们可以通过当前正在执行的文件的位置获得绝对路径,例如file1.py
,然后提取所需的父目录。因此,无论绝对路径是否改变,这都可以工作,因为我们获得它的方式总是相对于file1.py
。试试这个:
项目/folder1/file1.py
from pathlib import Path
import sys
sys.path.append(str(Path(__file__).parent.parent.parent)) # 1. <.parent> contains this file1.py 2. <.parent.parent> contains folder1 3. <.parent.parent.parent> contains Project
... the rest of the file
TL;DR
你可以通过为你的项目创建一个setup.py
文件,然后运行pip install -e .
来解决这个问题,而不是修改sys.path
。
这个答案似乎来自这个问题,但我把它放在这里,因为OP对这个解决方案表现出兴趣,我认为这通常是一个更好的解决方案与sys.path
打交道。
我倾向于为我的项目创建一个实际的setup.py,就好像我要将它们发布到PyPI,然后运行pip install -e .
使它们实际安装在我的(可能是虚拟的)python环境中。
这是一个极简的setup.py
,类似于我之前使用的:
from setuptools import setup
setup(
name="project",
version="0.0.1",
python_requires=">=3.6",
author="Some cool dude",
long_description="Some cool project",
install_requires=["dep1", "dep2"],
)
在另一个项目中,我在我的setup.py
中读取我的requirements.txt
文件:
from setuptools import setup
with open("requirements.txt") as f:
requirements = f.read().splitlines()
setup(
name="project",
version="0.0.1",
python_requires=">=3.6",
author="Some cool dude",
long_description="Some cool project",
install_requires=requirements,
)
无论哪种解决方案,setup.py
文件都是我的project
目录的兄弟(我总是使用小写的项目名称),通常都在我的Git repo的根目录下,或者在src
子目录下。
cd到setyp.py
和project
所在的目录,然后执行
pip install -e .
,现在从任何地方,你可以import project
或它的子模块,Python会找到它们。
推荐阅读
更多关于setup.py
文件的细节可以在setup.py示例中找到?
我在Windows操作系统中遇到了同样的问题。除了可能作为父级注入之外,sys.path.append的问题在于它创建了一个windows路径,尽管它被添加到sys.path中,但Python由于某种原因没有搜索该路径。请尝试使用
ROOT_PATH = pathlib.Path(__file__).parents[1]
sys.path.append(os.path.join(ROOT_PATH, ''))
它将把文件的祖父级添加到sys。