imp.find_module()支持拉链蛋

gue*_*tli 4 python python-import

imp.find_module()找不到压缩蛋的模块.

如何找到可以来自这两个地方的模块:目录或压缩蛋?在我的情况下,重要的是我可以提供path像imp.find_module()这样的参数.

背景

以某种方式在我们的环境中安装两次包.作为拉链蛋和普通文件.我想写一个检查,告诉我模块是否安装了两次.请参阅/sf/answers/1679369261/

fpb*_*bhb 5

假设Python 2,我认为你需要的信息是在PEP 302中 - 新的导入钩子(PEP在Python 3中已经过时了,在这方面完全不同).

从ZIP档案中查找和导入模块是在zipimport中实现的,它被"挂钩"到PEP描述的导入机制中.当PEP 302和从ZIP导入添加到Python时,imp模块没有被调整,即imp完全不知道PEP 302挂钩.

"通用" find_module功能查找模块喜欢imp尊重PEP 302个挂钩,将大致是这样的:

import imp
import sys

def find_module(fullname, path=None):
    try:
        # 1. Try imp.find_module(), which searches sys.path, but does
        # not respect PEP 302 import hooks.
        result = imp.find_module(fullname, path)
        if result:
            return result
    except ImportError:
        pass
    if path is None:
        path = sys.path
    for item in path:
        # 2. Scan path for import hooks. sys.path_importer_cache maps
        # path items to optional "importer" objects, that implement
        # find_module() etc.  Note that path must be a subset of
        # sys.path for this to work.
        importer = sys.path_importer_cache.get(item)
        if importer:
            try:
                result = importer.find_module(fullname, [item])
                if result:
                    return result
            except ImportError:
                pass
    raise ImportError("%s not found" % fullname)

if __name__ == "__main__":
    # Provide a simple CLI for `find_module` above.
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("-p", "--path", action="append")
    parser.add_argument("modname", nargs='+')
    args = parser.parse_args()
    for name in args.modname:
        print find_module(name, args.path)
Run Code Online (Sandbox Code Playgroud)

但请注意,在ZIP存档中查找模块的结果与imp.find_module返回的结果完全不同:您将获得zipimport.zipimporter特定ZIP 的对象.当被要求从压缩蛋中找到常规模块,内置模块和模块时,上面的litte程序会打印以下内容:

$ python find_module.py grin os sys
<zipimporter object "<my venv>/lib/python2.7/site-packages/grin-1.2.1-py2.7.egg">
(<open file '<my venv>/lib/python2.7/os.py', mode 'U' at 0x10a0bbf60>, '<my venv>/lib/python2.7/os.py', ('.py', 'U', 1))
(None, 'sys', ('', '', 6))
Run Code Online (Sandbox Code Playgroud)