11

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

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

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

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

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

4

4 回答 4

24

“我有一个中等大小的 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 多个模块,十几个包。每个模块只导入它需要的东西。没有魔法。

于 2009-05-22T10:05:51.857 回答
6

几个指针

  1. 您可能已经在各个模块中拆分了功能。如果在大多数情况下正确完成,您将不会陷入循环导入问题(例如,如果模块 a 依赖于 b 并且 b 依赖于 a,您可以制作第三个模块 c 来消除这种循环依赖)。作为最后的手段,在 a import b 但在 b import a 在需要 a 的地方,例如在函数内部。

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

  3. from module import * 可能不是一个好主意。相反,导入任何需要的东西。它可能是完全合格的。冗长并没有什么坏处。例如从 pakageA.moduleB 导入 CoolClass。

于 2009-05-22T02:20:43.087 回答
4

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

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

于 2009-05-22T09:10:17.553 回答
3

您不会在导入时得到递归,因为 Python 会缓存每个模块并且不会重新加载它已经拥有的模块。

于 2009-05-22T02:17:58.037 回答