整理您的代码文件

在 JupyterLab, 中处理 Python 脚本和笔记本文件时,您可能会将代码拆分为多个文件,以便于维护,并能在多个文件中使用实用函数,而无需将这些函数的定义复制到每个文件中。 在 Python 中,您可以通过包含 Python 定义和语句的模块,以及作为模块集合的包来实现这一点。

详情请参阅 “模块与包 ”。 通过使用 Python 导入语句,可以将一个模块中的 Python 代码提供给另一个模型中的 Python 代码使用。 详情请参阅 “导入系统”

如果您希望在 JupyterLab 中运行这些文件,或将其作为代码包资源部署在部署空间中,并确保操作规范且可靠,那么正确组织这些文件至关重要。

以下各节介绍了确保在 JupyterLab 中的文件以及在部署空间中运行代码包的作业中, Python 导入功能正常运行的推荐最佳实践。

在 JupyterLab 中组织文件

打开 JupyterLab, 后,您将在左侧边栏的 “文件浏览器 ”选项卡中看到以下两个文件夹:

  • assettypes
  • assets

这些文件夹非常重要,因为它们包含项目资源(如 Data Refinery 流程和数据资源),因此不应用于存储任何代码文件。

假设你有一个笔记本文件( main.ipynb )或一个 Python 脚本( main.py ),用于启动代码文件(也称为主模块)的执行,并且你在名为 utils. 的文件夹中还有 2 个辅助文件。

您可以按以下方式保存文件:

示例 1:

assettypes
assets
main.py
main.iypnb
utils
    helper.py
    helper2.py

或者,您可以按以下方式存储文件,以便更好地区分代码文件和非代码文件:

示例 2:

assettypes
assets
src
    main.py
    main.iypnb
    utils
        helper.py
        helper2.py

从主模块导入模块

要从名为 main.py 或 的主模块中 main.iypnb导入该 helper 模块,请使用:

  • 关于示例 1 中的文件夹结构:

    import utils.helper as helper
    
  • 关于示例 2 中的文件夹结构:

    import src.utils.helper as helper
    

如果采用示例 2 中所示的文件夹结构 import utils.helper as helper ,某些工具将允许您使用该路径,因为运行脚本或笔记本所在的文件夹会自动添加到 Python 路径中。 不过,由于并非所有工具都支持这种做法,因此你应该始终使用绝对导入。 请参阅 “包内引用”

如果你在用作主模块的模块中使用了相对路径,而你的工具不支持相对路径,可能会收到类似以下的导入错误信息:

ImportError: attempted relative import with no known parent package

从其他模块导入模块

在那些不作为主模块的模块中(即永远不会启动执行,但总是被导入的模块),你可以使用相对文件路径链接。

例如,如果你想 helper.py 引入来自 helper2.py的代码,可以使用:

from . import helper2

在代码包中组织文件

如果您希望将代码作为代码包部署到部署空间中,请确保您创建的 ZIP 压缩包包含运行代码所需的所有文件,并且这些文件的文件夹结构应与您在 JuypterLab 中使用的结构一致,以确保代码中的导入语句能够正确解析。

示例 1 的 ZIP 文件夹结构:

main.py
main.iypnb
utils
    helper.py
    helper2.py

示例 2 的 ZIP 文件夹结构:

src
    main.py
    main.iypnb
    utils
        helper.py
        helper2.py

如果你在示例 2 的 ZIP src 文件中未包含 ,你的绝对导入将无法正常工作。

包的文件夹命名规范

为包选择文件夹名称时,请务必注意,所选名称不能与运行环境中通过预装库导入的模块名称相同,否则会导致冲突。

例如,如果在示例 2 中,您使用名为 code 的文件夹代替 src ,并在默认的 Python 环境中运行以下代码:

import code.utils

你会看到一条错误信息,指出没有名为 的模块 code.utils ,且 code 不是一个包。

出现此错误是因为已经存在一个 code 名为 的模块,因此 code 无法作为包。

如果您不确定如何为文件夹包命名,可以运行以下命令进行测试:

import myproposedfoldername

您应收到以下响应:

ModuleNotFoundError: No module named 'myproposedfoldername'

如果未看到该响应,说明该名称已被系统中的某个模块占用,因此不应使用。