【问题标题】:Why is a Python import implicitly executing parent modules?为什么 Python 导入会隐式执行父模块?
【发布时间】:2020-07-04 13:29:44
【问题描述】:

作为Python documentation states,模块导入(以及从模块中导入)总是在执行可能的父模块。例如这些构成常规包的文件:

a_package/
  __init__.py
  a_submodule.py

从a_submodule 在完全不同的包中导入,例如

from a_package.a_submodule import an_object

将首先执行a_package/__init__.py,然后再执行a_package/a_submodule.py,并最终将an_object绑定到声明导入的命名空间中。

我想知道这背后的设计原理或技术必要性是什么。特别是因为这对我来说似乎违反直觉,因为通常的包制度是一个有序图,其中父模块取决于其子包中的内容,反之亦然。事实上,如果该 import 语句示例在 a_package/__init__.py 中进行了评估,它不会触发自身的执行。当然,因为这是一个循环依赖,但它表明子模块不依赖于它们的父模块。

【问题讨论】:

    标签: python python-3.x python-module


    【解决方案1】:

    有几个原因。从能力的角度来看,最重要的是包可以使用__path__ 之类的机制来帮助find它的子模块,如果在继续子模块导入之前没有配置它显然是行不通的.另一个是方便:如果一个包在其模块可以使用之前需要初始化,可以将它放入__init__.py,而不是让每个模块都需要from . import startup。

    此外,应该在什么其他时间初始化包?等到 all 子模块被导入是没有意义的,因为这可能永远不会发生;虽然它可能是“在子模块的第一次导入完成之后”,但这仍然是在其他子模块的导入之前,并且会不一致和任意。特别是,任何模块都不能使用其父 __init__.py 的内容,以防它是其兄弟姐妹中第一个被导入的。

    至于循环依赖,Python 一直支持这些(至少对于绝对导入):导入一个已经被导入的模块只会产生一个对模块对象的引用(处于其部分形成的状态) . from . import foo 的行为(顺便说一句,作为执行 __init__.py 的一部分通常是一个坏主意)也不例外;因为无论如何“额外导入”只是进入sys.modules,它根本没有任何作用。

    【讨论】:

      猜你喜欢
      • 2014-06-07
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 2015-12-27
      • 2014-01-09
      • 2014-08-17
      • 1970-01-01
      相关资源
      最近更新 更多