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

mle*_*ast 2 python python-import python-3.x

我想问一下是否有办法从与另一个文件夹相邻的项目中的文件夹中导入模块/函数。

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

project/src/training.py
project/lib/functions.py
Run Code Online (Sandbox Code Playgroud)

现在这两个文件夹中都有__init__.py文件。如果我想导入functions.pytraining.py,它似乎没有检测到。我正在尝试使用from lib.functions import *.I 知道这在文件夹结构的上层起作用,我可以从脚本调用这两个文件,但是有没有办法在上面/侧面文件夹中执行文件?

jpm*_*c26 5

从根本上说,做到这一点的最佳方式取决于这两个模块的确切关系。有两种可能:

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

内聚单位

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

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

project/
    trainingproject/
        __init__.py
        training.py
        functions.py
    other/
        ...
    project/
        ...
    folders/
        ...
Run Code Online (Sandbox Code Playgroud)

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

training.py

from . import functions

# The rest of training.py code
Run Code Online (Sandbox Code Playgroud)

假设您当前的目录是project,那么您可以training.py作为模块调用:

python -m trainingproject.training
Run Code Online (Sandbox Code Playgroud)

独立单元

如果您的模块实际上是单独的包,那么在开发过程中最简单的惯用解决方案是修改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
Run Code Online (Sandbox Code Playgroud)

PowerShell 语法:

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

(这在命令提示符中也是可能的,但我忽略了这一点,因为 PowerShell 是首选。)

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

training.py

import functions

# Rest of training.py code
Run Code Online (Sandbox Code Playgroud)

如果您复制所有文件并设置正确的路径,那么在将代码部署到生产环境时也可以这样做,但是您可能需要考虑functions.py安装一个轮子,然后使用 pip 安装它。这将消除PYTHONPATH通过安装functions.py到站点包进行设置的需要,这将使import语句开箱即用。这也将使分发functions.py其他独立于training.py. 我不打算在这里介绍如何创建轮子,因为这超出了本问题的范围,但这里有一个介绍