我正在尝试重新实现基于imp
模块的一些代码,以便使用importlib
。函数imp.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
专门使用特定路径?
答案 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)
我认为您对imp
和importlib
的使用可能不正确。路径列表应该是目录的路径,而不是特定的.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()]))