如何从父子目录导入模块

时间:2019-06-28 12:03:47

标签: python python-import

我想从父目录中目录中的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代码中,当我开始输入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代码运行文件,该文件是从父目录开始的。我还从使用

的sim文件夹的Windows命令行中尝试过
python run_simulation.py

3 个答案:

答案 0 :(得分:2)

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

为此,请按照下列步骤操作:

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。使用时,将terminal命令替换为

$ pipenv install -e .

使您的项目被添加到Pipfile中。

答案 1 :(得分:1)

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

答案 2 :(得分: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)

某事告诉我,这样做可能更容易,但我不知道如何。