【问题标题】:Properly importing modules in Python在 Python 中正确导入模块
【发布时间】:2009-05-22 02:09:07
【问题描述】:

如何设置模块导入,以便每个模块都可以访问所有其他模块的对象?

我有一个中等大小的 Python 应用程序,其模块文件位于各种子目录中。我创建了将这些子目录附加到sys.path 的模块,并使用import thisModule as tm 导入了一组模块。模块对象以该限定条件引用。然后我使用from moduleImports import * 将该模块导入到其他模块中。代码现在很草率,其中有一些东西,通常是重复的。

首先,应用程序失败,因为未分配一些模块引用。相同的代码在单元测试时会运行。

其次,我担心我会导致递归模块导入出现问题。导入 moduleImports 会导入 thisModule,后者会导入 moduleImports。 . . .

这样做的正确方法是什么?

【问题讨论】:

标签: python python-import


【解决方案1】:

“我有一个中等大小的 Python 应用程序,模块文件位于各个子目录中。”

很好。确保每个目录都包含一个__init__.py 文件,这样它就是一个包。

“我创建了将这些子目录附加到 sys.path 的模块”

不好。使用PYTHONPATH 或安装整个结构Lib/site-packages。不要动态更新sys.path。这是一件坏事。难以管理和维护。

“导入一组模块,使用import thisModule as tm。”

没有意义。也许您的结构中的每个模块都有一个import thisModule as tm。这是典型的标准做法:只导入您需要的模块,不导入其他模块。

“然后我用from moduleImports import *将该模块导入其他模块”

不好。不要一概导入一堆随机的东西。

每个模块都应该有一个长长的列表,列出它需要的具体内容。

import this
import that
import package.module

显式列表。没有魔法。 sys.path 没有动态变化。

我目前的项目有 100 个模块,十几个包。每个模块只导入它需要的东西。没有魔法。

【讨论】:

  • 一句话概括:“显式胜于隐式。”
【解决方案2】:

几个指针

  1. 你可能已经分手了 各种模块中的功能。如果 大多数时候你都正确地完成了 不会陷入循环进口 问题(例如,如果模块 a 依赖 在 b 和 b 上,你可以做第三个 模块 c 删除此类通知 依赖)。作为最后的手段,在 进口 b 但在 b 进口 a 在 需要 a 的点,例如里面 功能。

  2. 一旦功能正确 模块将它们分组在下面的包中 一个子目录并添加一个__init__.py 文件 到它,以便您可以导入 包裹。将此类包裹保存在 文件夹,例如lib,然后添加 到 sys.path 或设置 PYTHONPATH 环境 变量

  3. 从模块导入 * 可能不会 是个好主意。相反,导入任何东西 是需要的。它可能是完全合格的。它 冗长并没有什么坏处。例如 从 packageA.moduleB 导入 酷类。

【讨论】:

  • 次要格式说明:我相信您的意思是 init.py(在其周围使用反引号以防止将其转换为粗体。)
  • 谢谢,这些简单的格式化语言有时会变得难以管理
  • 我不明白你所说的“拆分功能”是什么意思,或者第三个模块如何帮助解决两个模块之间的相互依赖关系。
【解决方案3】:

做到这一点的方法是避免魔法。换句话说,如果你的模块需要来自另一个模块的东西,它应该显式地导入它。你不应该依赖自动导入的东西。

正如 Python 之禅 (import this) 所说,显式优于隐式。

【讨论】:

    【解决方案4】:

    您不会对导入进行递归,因为 Python 会缓存每个模块,并且不会重新加载它已有的模块。

    【讨论】:

    • 循环导入确实可以发生,例如假设 b 定义了 a 使用的函数,并且两者都相互导入,请参阅copypastecode.com/codes/view/5193
    • @Anurag Uniyal:你实际测试过吗? import 会跟踪它导入的内容,因此无法保证即使该代码也会导致递归加载。
    • 它确实发生了我现在不记得确切的细节,但它与导入两次作为主模块然后作为模块导入的相同模块有关
    猜你喜欢
    • 2020-01-10
    • 2021-02-04
    • 2013-05-29
    • 2020-12-23
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    相关资源
    最近更新 更多