Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python imp.find_module()支持压缩鸡蛋_Python_Python Import - Fatal编程技术网

Python imp.find_module()支持压缩鸡蛋

Python imp.find_module()支持压缩鸡蛋,python,python-import,Python,Python Import,找不到来自压缩鸡蛋的模块 如何找到来自两个地方的模块:目录或压缩鸡蛋?在我的例子中,重要的是我可以提供一个像imp.find_module()这样的path参数来支持它 背景 不知何故,软件包在我们的环境中安装了两次。像拉链鸡蛋和普通文件一样。我想写一张支票,告诉我一个模块是否安装了两次。请参见假设使用Python 2,我认为您需要的信息就在其中(对于Python 3,PEP已经过时,这在这方面是完全不同的) 从ZIP归档文件中查找和导入模块是在中实现的,如PEP所述,它“挂钩”到导入机制中。当

找不到来自压缩鸡蛋的模块

如何找到来自两个地方的模块:目录或压缩鸡蛋?在我的例子中,重要的是我可以提供一个像imp.find_module()这样的
path
参数来支持它

背景


不知何故,软件包在我们的环境中安装了两次。像拉链鸡蛋和普通文件一样。我想写一张支票,告诉我一个模块是否安装了两次。请参见

假设使用Python 2,我认为您需要的信息就在其中(对于Python 3,PEP已经过时,这在这方面是完全不同的)

从ZIP归档文件中查找和导入模块是在中实现的,如PEP所述,它“挂钩”到导入机制中。当PEP 302和从ZIP导入被添加到Python中时,
imp
模块没有被修改,即
imp
完全不知道PEP 302钩子

查找模块(如
imp
)的“通用”
find_module
函数符合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)
但是请注意,在ZIP存档中查找模块的结果与
imp.find_module
返回的结果大不相同:对于特定的ZIP,您将得到一个
zipimport.zipimporter
对象。当要求查找常规模块、内置模块和压缩鸡蛋中的模块时,上面的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))
$python find_module.py grin操作系统
(,'/lib/python2.7/os.py',('.py',U',1))
(无、‘系统’、(‘系统’、‘6))

如果您的模块深入到压缩鸡蛋中的包层次结构中,该怎么办?在这种情况下,您希望走哪条路?没有与您请求的模块直接等效的文件。@Kevin imp.find_module()只查找“顶级”模块。例如,您可以找到“os”,但找不到“path”(如“os.path”)。我只需要一个find_module(),它的工作方式与python解释器的import语句类似。解释器加载压缩鸡蛋。2.x中的导入机制未完全公开。在3.x下,你可以通过
importlib
得到你想要的<代码>导入已弃用。不幸的是,这也意味着整个事情比
imp
任何时候都要复杂得多。@Kevin谢谢你的提示<代码>导入lib甚至存在于Python2.7中。它是一个子集,但可能比没有要好。importer.find_模块(全名)的调用不会传递
path
参数。如果路径不是sys.path,这将导致返回错误结果。我现在使用:我已经更新了代码。它现在将正确执行路径
。我的意思是解释发生了什么。您将
路径
传递给
导入程序。查找模块()
。但是,假设zipimporter忽略了参数
path
:-(是的,我知道它被
zipimporter
忽略。但是可能安装了其他使用
path
的导入钩子。在我的回答中,我更笼统地回答了您的问题,因为Python解释器将以与真正的
import
实现类似的方式找到任何模块(模块化了Python 2中import.c、PEP 302等复杂的相互作用所带来的困难)。