包:避免在仅将其中一个成员导入 __init__.py 时导入整个模块

package: avoid importing the entire module when importing only one of its members into __init__.py

对不起,如果标题不是很清楚,但我没有很好地总结。 我正在试验包,我处于这种情况:

$:~/project$ tree
.
├── first_mod.py
└── first_package
    ├── __init__.py
    └── sub_package
        ├── __init__.py
        └── second_mod.py

在第一个 __init__.py inside first_package 目录中我指定了这个内容:

from first_package.sub_package.second_mod import function

(显然在模块second_mod中有一个函数叫做function

如果我在目录 project 中打开解释器并导入 first_package 然后尝试使用制表符自动完成查看它包含的内容,除了 function [=21] =] 也被列出。

>>> import first_package
>>> first_package.                             [tab]
first_package.function(    first_package.sub_package

问题是:__init__.py中只导入function时,难免sub_package也显示为first_package的内容吗?

手头的行为可以用 运行 导入模块 baz 时发生的情况的简短说明来解释,其中包含 import foo.bar.baz.

之类的语句

1: 导入父模块

在可以导入 baz 之前,bar 需要存在。在可以导入 bar 之前,foo 需要存在 - python 无法通过快捷方式到达 baz

2:运行宁__init__.py个文件

直到 baz 之前导入的每个包都有一个 __init__.py 文件,该文件会被执行。

3: 将遇到的模块加载到 sys.modules

当一个文件夹作为包导入时,其中所有python个文件都作为模块导入(不包括__init__.py个文件,可以想象成包本身的替身) .它们将被加载到 sys.modules 中并且可供包对象访问(在本例中为 foo、``bar, and baz`)。


差不多就这些了,具体细节可以查here

在您的示例中,执行了两个 import 语句(一个由您执行,另一个在 first_package/__init__.py 为 运行 时执行),但只有第一个语句是解释发生的事情所必需的。当您导入 first_package 时,第三步加载属于包的所有模块。这包括 sub_package,使用标准导入机制无法绕过它。

运行

del first_pacakge.sub_package

会在您只关心它的情况下将其从对象中删除,但它不会卸载它,它仍会在 sys.modules.