2

imp我正在尝试根据要使用的模块重新实现一些代码importlibimp.find_module函数和之间存在细微差别importlib.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使用特定路径?

4

3 回答 3

1

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

例如,我在本地文件中定义了一些自定义 Fabric pip 函数pip.py,但我也想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()]))
于 2015-04-20T18:44:19.157 回答
1

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

其次,从标准库返回 abc,因为它已经在 sys.modules 中。请记住,importlib.find_loader() 会查找指定模块的加载程序,因此这包括查找sys.modules['abc'].__loader__以跳过尝试不必要地查找它。如果您在标准库中指定了一个尚未导入的模块(例如 tokenize),那么 importlib.find_loader() 将返回 None。

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

于 2013-03-26T13:04:13.243 回答
1

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

于 2013-03-28T12:37:25.327 回答