从Python中的相邻文件夹导入模块

时间:2019-04-02 22:11:20

标签: python python-3.x python-import

我想问一下是否有一种方法可以从项目中与另一个文件夹相邻的文件夹中导入模块/功能。

例如,假设我有两个文件:

project/src/training.py
project/lib/functions.py

现在,这两个文件夹中都有__init__.py文件。如果我想将functions.py导入到training.py中,似乎无法检测到。我正在尝试使用from lib.functions import *。我知道这可以在文件夹结构的上层工作,在这里我可以从脚本中调用两个文件,但是有没有办法在上方/侧向文件夹中进行文件处理?

3 个答案:

答案 0 :(得分:1)

是的,就像从工作目录中写入整个路径一样简单:

from project.src.training import *

from project.lib.functions import *

答案 1 :(得分:1)

从根本上说,执行此操作的最佳方法取决于两个模块的确切关联方式。有两种可能性:

  1. 模块是一个内聚单元的一部分,旨在用作一个整体,而不是单独使用。 (这是最常见的情况,如果不确定,应将其作为默认设置。)
  2. functions.py模块是training.py的依赖项,但应单独使用。

内聚单元

如果模块是一个内聚单元,则这不是在Python中构建项目的标准方法。

如果同一项目中需要多个模块,则构造文件夹的标准方法是将所有模块都包含在一个package中,如下所示:

project/
    trainingproject/
        __init__.py
        training.py
        functions.py
    other/
        ...
    project/
        ...
    folders/
        ...

__init__.py文件使Python将trainproject/目录识别为称为包的单个单元。使用软件包可以使用相对导入

training.py

from . import functions

# The rest of training.py code

假设当前目录为project,则可以将training.py作为模块调用:

python -m trainingproject.training

单独的单位

如果您的模块实际上是单独的程序包,那么在开发期间最简单的惯用解决方案是修改PYTHONPATH环境变量:

sh衍生语法:

# All the extra PYTHONPATH references on the right are to append if it already has values
# Using $PWD ensures that the path in the environment variable is absolute.
PYTHONPATH=$PYTHONPATH${PYTHONPATH:+:}$PWD/lib/
python ./src/training.py

PowerShell语法:

$env:PYTHONPATH =  $(if($env:PYTHONPATH) {$env:PYTHONPATH + ';'}) + (Resolve-Path ./lib)
python ./src/training.py

(这在命令提示符中也是可能的,但是由于首选PowerShell,所以我省略了它。)

在您的模块中,您只需执行普通的import语句:

training.py

import functions

# Rest of training.py code

如果将所有文件复制并设置正确的路径,则在将代码部署到生产环境时,也可以执行此操作,但是您可能需要考虑将functions.py放入一个轮子,然后用点子安装它。这将消除通过在站点软件包中安装PYTHONPATH来设置functions.py的需要,这将使import语句立即可用。这也将使分发functions.py以便与training.py独立的 other 脚本一起使用变得更加容易。我不在这里介绍如何创建转盘,因为这超出了此问题的范围,但这里是an introduction

答案 2 :(得分:0)

我同意上面所说的什么。如果您还想知道导入这些特定脚本或函数后如何运行,请使用:your_function_name(parameters),以及运行从同一目录导入的脚本,等等,请使用:exec('script_name.py) 。我建议使用函数而不是使用exec命令,因为正确使用它可能会有点困难。