如何从父级子目录导入模块

5

我想从父目录中的一个目录中的Python文件中导入一个类(class)。 这是当前的文件夹结构:

│   run_simulation_from_parent.py
│   __init__.py
│
├───.vscode
│       launch.json
│       settings.json
│
├───mod
│   │   mods.py
│   │   __init__.py
│   │
│   └───__pycache__
│           __init__.cpython-37.pyc
│
├───sim
│   │   run_simulation.py
│   │   __init__.py
│   │
│   └───__pycache__
│           __init__.cpython-37.pyc
│
└───__pycache__
        __init__.cpython-37.pyc

文件mod/mods.py 包含以下类:
class Objective:
    """Objective function class"""

    def __init__(self, x):
        self.x = x

文件sim/run_simulation.py包含以下内容:
from mod.mods import Objective

x = 5
obj = Objective(x)

当我尝试运行这段代码时,我得到了以下错误信息:

  File "sim/run_simulation.py", line 1, in <module>
    from mod.mods import Objective
ModuleNotFoundError: No module named 'mod'

在 Visual Studio Code 中,当我开始输入 mod.modsimport Objective 时,它会自动填充。

当我运行以下内容的 run_simulation_from_parent.py 时,没有任何问题:

from mod.mods import Objective

x = 5
obj = Objective(x)

print(obj.x)

我该如何在目录sim下执行此操作?我已经尝试了以下方法:
  1. 使用 from ..mod.mods import Objective 在 run_simulation.py 中执行。
  2. 使用以下内容的 init.py 文件:import os, sys sys.path.append(os.path.dirname(os.path.realpath(__file__)))
  3. 不使用 __init__.py 文件。

编辑:我是从 Visual Studio Code 运行文件的,起始目录为父级目录。我还尝试从 Windows 命令行中的 sim 文件夹运行,其中我使用了:

python run_simulation.py

可能是从子目录导入文件?的重复问题。 - user10722301
@user3223765,你能告诉我你是如何使用这个项目的吗?也就是说,你是从哪里运行run_simulations.py文件的?也就是你是如何在终端中运行它的? - sahasrara62
我从Visual Studio Code中运行文件,其中我从父目录开始。 - user3223765
3个回答

5

我处理项目内部导入的方式是在可编辑模式下安装项目。这样,所有文件都能够相互定位,始终从你的项目根目录开始。

要执行此操作,请按照以下步骤进行:

1) 编写setup.py文件并将其添加到项目根文件夹中 - 它不需要太多信息:

# setup.py
from setuptools import setup, find_packages

setup(name='MyPackageName', version='1.0.0', packages=find_packages())

2) 安装您的软件包以可编辑模式(最好从虚拟环境中)。在项目文件夹的终端中,输入以下内容:

$ pip install -e .

注意这个点-它表示“以可编辑模式从当前目录安装软件包”。
3)你项目内的文件现在可以相互定位,始终以项目根目录为起点。例如,要导入Objective,你需要编写:
from mod.mods import Objective

不管项目结构中文件的位置在哪里,导入Objective都是正确的。

如我所说,您应该为此使用虚拟环境,这样pip就不会将软件包安装到您的主Python安装中(如果您的项目有很多依赖项,这可能会很混乱)。

我最喜欢的工具是pipenv。在使用它时,请使用以下终端命令进行替换。

$ pipenv install -e .

这样你的项目才能被添加到 Pipfile 中。


感谢您详细的解释!我尝试了您所说的并使用了 'setup(name='Objective', version='1.0.0', packages=find_packages())',然后运行了 pip 命令,创建了一个名为 Objective.egg-info 的文件夹。但是它并没有解决我的问题... - user3223765

1

我找到了一种解决方案,即将其添加到系统路径中:

import os
import os.path
import sys

sys.path.append(os.getcwd() + "\\mod")

from mods import Objective

x = 5
obj = Objective(x)

print(obj.x)

这个可以运行,但我不认为这是原本的意图...
编辑:以下内容更加通用:
import os
import sys

sys.path.append(os.getcwd())

from mod.mods import Objective

x = 5
obj = Objective(x)

print(obj.x)

我觉得这个可以更简单地完成,但是不知道如何实现。


1
使用 from ..mod.mods import Objective 并保留所有的 __init__.py 文件。

抱歉,OP 中有一个打字错误。我已经尝试过..mod.mods。 - user3223765

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接