imp.find_module() which supports zipped eggs

后端 未结 1 1671
独厮守ぢ
独厮守ぢ 2021-01-19 09:26

imp.find_module() does not find modules from zipped eggs.

How can find modules which can come from both places: directories or zipped eggs? It is im

相关标签:
1条回答
  • 2021-01-19 09:58

    Assuming Python 2, the information I think you need is in PEP 302 - New Import Hooks (the PEP is outdated for Python 3, which is completely different in this regard).

    Finding and importing modules from ZIP archives is implemented in zipimport, which is "hooked" into the import machinery as described by the PEP. When PEP 302 and importing from ZIPs were added to Python, the imp modules was not adapted, i.e. imp is totally unaware of PEP 302 hooks.

    A "generic" find_module function that finds modules like imp does and respects PEP 302 hooks, would roughly look like this:

    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)
    

    Note, though, that the result from finding a module in a ZIP archive looks quite different to what imp.find_module returns: you'll get a zipimport.zipimporter object for the particular ZIP. The litte program above prints the following when asked to find a regular module, a built-in module and a module from a zipped egg:

    $ 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))
    
    0 讨论(0)
提交回复
热议问题