使用importlib
," Meta Path Finder"之间有什么区别? (通过遍历sys.meta_path找到)和Path Entry Finder" (通过遍历sys.path_hooks找到)?
第一种类型在导入开始时调用,但何时使用第二种类型?两者都返回一个spec对象?
我想实现自定义导入,其中可以从* .py或* .pyc以外的来源导入模块,例如从一个流。怎么办呢?
答案 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.path
和sys.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中汇总了更多详细信息(包含更多链接)。