imp.find_module() 支持压缩鸡蛋
imp.find_module() which supports zipped eggs
imp.find_module() 没有从 zipped eggs 中找到模块。
如何找到 可以来自两个地方的模块:目录或压缩的鸡蛋?在我的案例中,重要的是我可以提供一个 path
参数,例如 imp.find_module() 支持它。
背景
不知何故,软件包在我们的环境中安装了两次。作为压缩鸡蛋和普通文件。我想写一个检查,告诉我一个模块是否安装了两次。参见
假设Python 2,我认为你需要的信息在PEP 302 - New Import Hooks中(PEP对于Python 3已经过时,在这方面完全不同)。
从 ZIP 档案中查找和导入模块在 zipimport 中实现,如 PEP 所述,它是 "hooked" 导入机器。当 PEP 302 和从 ZIP 导入被添加到 Python 时,imp
模块没有被改编,即 imp
完全不知道 PEP 302 钩子。
一个 "generic" 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)
但是请注意,在 ZIP 存档中查找模块的结果看起来与 imp.find_module
returns 完全不同:您将得到一个 zipimport.zipimporter
特定对象的对象压缩。当要求查找常规模块、内置模块和压缩鸡蛋中的模块时,上面的小程序会打印以下内容:
$ 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))
imp.find_module() 没有从 zipped eggs 中找到模块。
如何找到 可以来自两个地方的模块:目录或压缩的鸡蛋?在我的案例中,重要的是我可以提供一个 path
参数,例如 imp.find_module() 支持它。
背景
不知何故,软件包在我们的环境中安装了两次。作为压缩鸡蛋和普通文件。我想写一个检查,告诉我一个模块是否安装了两次。参见
假设Python 2,我认为你需要的信息在PEP 302 - New Import Hooks中(PEP对于Python 3已经过时,在这方面完全不同)。
从 ZIP 档案中查找和导入模块在 zipimport 中实现,如 PEP 所述,它是 "hooked" 导入机器。当 PEP 302 和从 ZIP 导入被添加到 Python 时,imp
模块没有被改编,即 imp
完全不知道 PEP 302 钩子。
一个 "generic" 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)
但是请注意,在 ZIP 存档中查找模块的结果看起来与 imp.find_module
returns 完全不同:您将得到一个 zipimport.zipimporter
特定对象的对象压缩。当要求查找常规模块、内置模块和压缩鸡蛋中的模块时,上面的小程序会打印以下内容:
$ 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))