【问题标题】:How to import modules that are used in both the main code and a module correctly?如何正确导入主代码和模块中使用的模块?
【发布时间】:2010-03-21 04:18:30
【问题描述】:

假设我有一个主脚本 main.py,它导入另一个带有 import coolfunctions 的 python 文件和另一个:import chores

现在,假设coolfunctions 也使用家务中的东西,因此我在coolfunctions 中声明import chores

因为 main.py 和 coolfunctions 都导入了家务~这是多余的吗?有没有其他方法可以做到这一点?我做得对吗?

我对 python 项目的一般结构感到困惑。我有一个“conf.py”文件,我导入了一堆变量~这是一个模块吗?我也在多个地方加载了这个 conf 文件。

【问题讨论】:

    标签: python file import module


    【解决方案1】:

    如果两个模块想要使用chores,那么每个必须 import chores(或一些等效的导入)。每个导入只在进行导入的模块的命名空间中创建一个名称绑定;也就是说,import 的命名空间效果是模块命名空间的本地化

    这很好,因为通过查看模块的代码,您可以(除非有病态的情况)通过显式将模块或模块属性绑定到名称的导入语句知道每个名称绑定到的位置。在其他模块中进行的导入不会影响此模块的命名空间。

    【讨论】:

      【解决方案2】:

      每个模块 X 应导入所有(且仅)模块 Y、Z、T...已经完成了部分或全部这些导入,或者将来可能会这样做。

      如果每个模块都必须担心这种微妙的“隐蔽通道”效应,它会使模块变得极其脆弱(实际上,这与模块化完全相反!)。

      Y、Z、T、...的其他模块,X 选择导入的每个模块(如果有的话)是 X 实现细节的一部分,除了编码、测试或维护的开发人员之外,不应涉及任何人十。

      为了确保情况确实如此,并且这种明显最好的解耦策略可以并且将完全遵循健全的代码,Python 在导入模块时“缓存”模块:一个模块仅“加载”一次每次运行程序时,任何人第一次导入它(或其中的任何内容) - 所有其他导入使用第一次加载获得的相同对象,Python 将其保存在缓存中(指定为 dict @987654321 @,但是您只需要了解一些高级编程技术的详细信息...不要担心,98.7% 的时间 - 只需记住“导入很便宜”!-)。

      当然,您通过import conf 从其他几个模块中使用的conf.py 绝对是一个模块(您可能认为您正在多次加载它,但除非您使用非常高级和深思熟虑,否则您不是技术确实是为了这个目的)——为什么不应该呢?

      【讨论】:

      • 如果上面的答案看起来有点混乱,请知道您可以将print 'loading mymodule' 之类的行直接放入 mymodule.py 的顶层。您将看到 print 语句在第一次导入时执行,但在第二次导入时不会执行。
      • python -v yourmain.py 也有帮助;-)。
      【解决方案3】:

      不,这不是多余的 - 在主模块和 coolfunctions 中都可以使用 import chores

      Python 的确切导入机制很复杂(例如,模块导入只进行一次,这意味着在您的情况下,chores 模块的实际解析和加载只会发生一次,这是一个很好的优化)但是一般来说,您不必担心它,因为它可以正常工作

      每个 Python 文件都是一个模块,因此您的 conf.py 也是一个模块。

      【讨论】:

        【解决方案4】:

        在使用它们的文件中导入所有必要的模块始终是最佳做法。举个例子:

        A.py 包含:import coolfunctions

        B.py 包含:import A

        Main.py 包含:import B 并使用 A.py 中定义的函数(这是可能的,因为通过导入 B,Main.py 已导入 B 导入的所有内容)

        如果以后你将 B.py 更改为功能而不需要导入 A.py 并因此删除 import A,那么你的 Main.py 将遭受没有导入 A 的损失。

        【讨论】:

        • 我不确定 Main.py 是否可以直接调用 A 中的函数,例如 A.funkyfunctions() 而不导入 A。你确定吗?
        • 不,绝对不是“通过导入 B,Main.py 导入了 B 导入的所有内容”的情况。通过执行import BMain 只导入了一个标识符:B。当且仅当B 定义(包括imports)标识符A 等时,它才能使用B.A
        • @Alex Martelli:我应该更好地表达我的回应,但我想说的是你所说的。 B 导入的所有内容现在都可以被 Main.py 访问,因为 Main.py 已经导入了 B。
        猜你喜欢
        • 2021-03-13
        • 2019-08-08
        • 2018-06-10
        • 1970-01-01
        • 2015-08-19
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多