如何强制importlib find_loader专门使用特定路径?

时间:2013-03-25 19:14:16

标签: python-importlib

我正在尝试重新实现基于imp模块的一些代码,以便使用importlib。函数imp.find_moduleimportlib.find_loader

之间存在细微差别
# Using imp find_module
>>> import imp
>>> imp.find_module("abc", ["some/path/module.py"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.3/imp.py", line 220, in find_module
    raise ImportError(_bootstrap._ERR_MSG.format(name), name=name)
ImportError: No module named 'abc'

# Using import find_loader
>>> import importlib
>>> loader = importlib.find_loader("abc", ["some/path/module.py"])
>>> loader.path
'/usr/lib64/python3.3/abc.py'

看起来importlib正在回退到系统库,而imp.find_module以独占方式使用path参数,最终会引发异常。

如何强制importlib.find_loader专门使用特定路径?

3 个答案:

答案 0 :(得分:1)

这取决于您的代码的确切目标。首先,两个调用都是错误的,因为'path'参数是一个目录列表,而不是一个特定的文件。

其次,abc是从标准库返回的,因为它已经存在于sys.modules中。请记住,importlib.find_loader()查找指定模块的加载器,因此包括查看sys.modules['abc'].__loader__以跳过尝试不必要地找到它。如果你在标准库中指定了一个模块(例如tokenize),那么importlib.find_loader()就会返回None。

换句话说,importlib.find_loader()将在'path'中指定时搜索特定目录中的模块,但您必须查找尚未导入的内容。

答案 1 :(得分:1)

我发现答案不是使用find_loader而是使用importlib.machinery.PathFinder类来查找特定路径中的模块。

答案 2 :(得分:1)

我认为您对impimportlib的使用可能不正确。路径列表应该是目录的路径,而不是特定的.py文件。您永远不会在module.py中找到abc.py,因此导入失败。

e.g。我在本地pip.py文件中定义了一些自定义Fabric pip函数,但我还想在我的site-packages目录中加载官方pip.py。由于我首先使用importlib导入我的自定义pip.py,这使import pip加载我的自定义版本。要在站点包中加载模块,我必须这样做:

from distutils.sysconfig import get_python_lib
import imp
real_pip = imp.load_module('pip', *imp.find_module('pip', [get_python_lib()]))