`sys.meta_path`和`sys.path_hooks`导入器对象有什么区别?

时间:2017-01-30 16:43:18

标签: python python-import python-module

使用importlib," Meta Path Finder"之间有什么区别? (通过遍历sys.meta_path找到)和Path Entry Finder" (通过遍历sys.path_hooks找到)?

第一种类型在导入开始时调用,但何时使用第二种类型?两者都返回一个spec对象?

我想实现自定义导入,其中可以从* .py或* .pyc以外的来源导入模块,例如从一个流。怎么办呢?

2 个答案:

答案 0 :(得分:2)

sys.path_hooks returns a finder factory

  

路径挂钩作为sys.path(或package.__path__)处理

的一部分进行调用

我们在PEP 302 relevant part中读到你应该阅读的内容,以便做你想做的事。

可以这么说,我们在代码中使用custom hook,但我不建议你逐字复制(我真的不确定我们用init文件做的hocus pocus)

然而,这个过程有点像那样 - find_module方法返回self或None,具体取决于你想要接受什么作为模块,load_module方法继续通过编译代码来加载它并为其分配一个sys.modules的条目。通过更换这些部件,你几乎可以加载任何你想要的东西。

相关:

答案 1 :(得分:2)

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

PathFinder中的sys.meta_path对象使用sys.pathsys.path_hooks。 (除了在Python< 3.4中,当PathFinder中没有任何内容可以加载模块时,sys.meta_path功能内置到解释器中。)

PathFinder遍历sys.path中的路径列表。对于每个路径,如果sys.path_importer_cache中的finder尚未针对该路径进行缓存,则会遍历sys.path_hooks中的可调用对象列表,并使用该路径调用每个路径以查看是否会产生发现者;它缓存了它在sys.path.importer_cache_中找到的第一个缓存。

一旦找到了查找程序,它就会通过find_spec()或已弃用的find_module()方法查询它,看看它是否可以找到该模块。如果是这样,它可以继续导入它,否则它将使用sys.path上的下一个路径开始上面的步骤。

这最初是在PEP 302中描述的,但PEP 451几乎是现代行为; importlib文档似乎是当前的规范。

我的personal notes中汇总了更多详细信息(包含更多链接)。