【问题标题】:Why does importing a python module not import nested modules?为什么导入 python 模块不导入嵌套模块?
【发布时间】:2012-03-07 08:57:01
【问题描述】:

如果我这样做:

import lxml 

在 python 中,lxml.html 不会被导入。例如,我不能调用lxml.html.parse() 函数。为什么会这样?

【问题讨论】:

  • 您可能会注意到import os 允许您在代码中使用os.path.whatever。所以,这取决于模块作者。

标签: python python-module


【解决方案1】:

在 Python 中导入模块或包是一个概念上简单的操作:

  1. 找到导入对应的.py文件。这涉及 Python 路径和其他一些机制,但会导致找到特定的 .py 文件。

  2. 对于导入中的每一级目录(import foo.bar.baz有两级),找到对应的__init__.py文件,并执行。执行它只是意味着运行文件中的所有顶级语句。

  3. 最后,.py 文件本身(在这种情况下为foo/bar/baz.py)被执行,这意味着所有顶级语句都被执行。由于该执行而创建的所有全局变量都捆绑到一个模块对象中,并且该模块对象是导入的结果。

如果这些步骤都没有导入子包,则这些子包不可用。如果他们确实导入了子包,那么它们是可用的。包作者可以随心所欲。

【讨论】:

  • 我认为值得澄清的是,在导入包时,在步骤 1 中找到的 .py 文件是包的 __init__.py。除非在该 __init__.py 文件中导入子包,否则它们将不可用。
  • from foo.bar import baz 不是不受这条规则的约束吗?至少就我的项目而言,即使所有 __init__.py 都是空的,所有此类导入工作也是如此。也请看a question I posted
【解决方案2】:

lxml 在 Python 中被称为 package,它是一个分层的模块集合。包可能很大,因此允许它们在导入时选择引入的内容。否则每个人都必须导入完整的层次结构,这将非常浪费资源。

【讨论】:

    【解决方案3】:

    这是设计使然。该包可以选择在其__init__.py 中导入嵌套包,然后,您将能够毫无问题地访问嵌套包。这是包编写者的选择问题,目的是尽量减少您可能不会使用的代码量。

    【讨论】:

      【解决方案4】:

      lxml 是一个包,而不是一个模块。包是模块的集合。碰巧,您也可以直接导入包,但这不会自动导入其所有子模块。

      至于为什么这是,嗯,这是 BDFL 的问题。我认为这可能是因为包通常很大,并且导入所有子模块会导致性能损失过大。

      【讨论】:

        【解决方案5】:

        这是为了只允许为您可能不会全部使用的多部分库加载最少量的代码。例如,您可能没有使用lxmlhtml 部分,因此不想处理加载它的代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-06
          • 2019-09-25
          • 1970-01-01
          • 1970-01-01
          • 2016-09-06
          相关资源
          最近更新 更多