您将看到两个完全不同的信息源,教程和语言参考。
教程部分
The Module Search Path
(除了只描述默认行为外)还只描述了实际导入模块时发生的情况。
如果模块已经在缓存中,则不会发生此过程。这里没有解释,因为上一节已经讨论过了,
More on Modules
以下内容:
模块可以包含可执行语句和函数定义。这些语句旨在初始化模块。它们只在import语句中第一次遇到模块名时执行。
…
注意:为了提高效率,每个模块在每个解释器会话中只导入一次。
它没有解释发生这种情况的机制,因为这只是一个教程。
同时,在导入系统的参考文档中,
module cache
部分解释了
import
陈述。
注意,如果模块已经被导入,python会避免执行模块的语句,或者为了提高效率只导入一次,这并不完全正确。这是默认加载程序将模块放在
sys.modules
隐藏物。如果您在事实发生后用缓存替换加载程序或monkey,那么实际上一个模块将被多次导入和执行。
下一节从下一节开始,
Finders and loaders
与本教程的“模块搜索路径”部分相比,类似地描述了如何找到模块的详细信息:
python包含许多默认的查找程序和导入程序。第一个知道如何定位内置模块,第二个知道如何定位冻结模块。第三默认查找器搜索模块的导入路径。
所以再说一遍,不是
确切地
确实,解释器首先搜索内置模块。相反,解释器只是按顺序搜索它的查找器,默认情况下,第一个查找器是内置的模块查找器。但如果更改查找器列表,python将不会首先搜索内置项。
事实上,如果你打印出来
sys.meta_path
在cpython 3.7的默认安装中,您将看到:
(在ipython下,或者如果您导入了
six
这有助于重命名模块,或者如果您导入了
requests
嵌入有版本控制的模块后,您将有几个额外的查找程序。)
那个
BuiltinImporter
记录在
importlib
图书馆文献。(如果你想知道为什么不叫它
BuiltinFinder
,同时也是其自身加载程序的finder称为importer)。
sys.builtin_module_names
调用特定于实现的函数来处理在那里找到的任何东西。
In CPython 3.6
(道歉在3.6到3.7之间来回跳动,但在这里不重要),它所调用的实现特定的功能是
_imp.create_builtin
,你可以从那里追踪到东西。
但需要注意的是
builtin_module_names
实际上是“内置”的,因为它是预先导入的。例如,在正常安装时,您可能会看到
_ast
在那里,但是没有
sys.modules['_ast']
是的。
所以
create_builtin
函数(或者,对于不同的实现,无论它使用什么来实现
室内搬运工
)必须能够导入预安装在python中的so/dll/pyd/dylib模块。