sys.meta_path和sys.path_hooks导入对象之间有什么区别?

mic*_*ael 5 python python-module python-import

使用importlib,“元路径查找器”(通过sys.meta_path遍历发现)和“路径条目查找器”(通过sys.path_hooks遍历发现)有什么区别?

第一种类型在导入开始时被调用,但是第二种类型何时使用?两者都返回规格对象吗?

我要实现自定义导入,可以从* .py或* .pyc以外的其他来源(例如,从流)导入模块。如何才能做到这一点?

Cur*_*son 7

当要导入一个模块时,解释器首先遍历 中的对象列表,对每个对象sys.meta_path调用find_spec()or (自 3.4 起已弃用)find_module()方法。)接口记录在importlib.abc.MetaPathFinder抽象基类中。)在检查任何其他导入器(包括冻结和内置)之前查询这些接口 ,因此可以覆盖任何其他导入处理。

PathFinderin的对象sys.meta_path是使用sys.path和的对象sys.path_hooks。(除了在 Python < 3.4 中,该PathFinder功能内置于解释器中,以便在sys.meta_path无法加载模块时使用。)

PathFinder通过的路径列表走sys.path。对于每条路径,如果finder尚未为该路径缓存,sys.path_importer_cache它会遍历 中的可调用列表,sys.path_hooks使用路径调用每个路径以查看它是否会生成一个 finder;它缓存它在 中找到的第一个sys.path.importer_cache_

一旦它找到了 finder,它就会通过find_spec()or deprecatedfind_module()方法查询它是否可以找到该模块。如果是这样,它可以继续导入它,否则它会从下一个路径开始上面的步骤sys.path

这最初在PEP 302 中描述,但PEP 451几乎是现代行为;在导入库文件似乎是目前的规范。

在我的个人笔记中总结了更多细节(带有更多链接)。


Mr_*_*s_D 2

sys.path_hooks返回一个查找器工厂

路径钩子作为 sys.path (或package.__path__)处理的一部分被调用

正如我们在PEP 302 相关部分中读到的中所读到的那样,您应该阅读该部分来执行您想要的操作。

说到这里,我们在代码中使用了自定义钩子,但我不建议您逐字复制它(我真的不确定我们对初始化文件所做的骗局)

然而,这个过程有点像那里 - 该find_module方法返回 self 或 None 取决于您想要接受的模块,并且该load_module方法通过编译代码并将其分配给sys.modules. 通过更换这些部件,您几乎可以加载任何您想要的东西。

有关的: