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