之前已被问过(例如here),但是给定的解决方案(即将文件重命名为*.so
)是不可接受的。我有一个名为name.dylib
的CPython扩展,无法导入。如果将文件名更改为使用name.so
,则会正确导入。更改文件名不是一个选择**,并且没有必要。
Python有很多用于搜索模块的钩子,因此必须有一种使其能够识别dylib文件的方法。有人可以显示如何执行此操作吗?使用低级导入(拼出整个文件名)不是很好,但是可以接受。
**,因为构建代码强制使用dylib,在其他上下文中,我也假设它。扩展模块是双重用途的,可以同时用作普通共享库和Python扩展。使用symlink确实可以,但是由于必须在自动化过程中进行手动干预,因此是最后的选择。
您可以操纵sys.path_hooks
,并用可接受sys.path_hooks
扩展名的钩子代替FileFinder
钩子。但是,请参阅更简单但不太方便的替代方法,在扩展名的完整文件名下将导入。
例如,在FileFinder
中可以找到.dylib
,.so
和.py
文件如何导入的更多信息。
此操作可能类似于以下内容:
.pyc
此必须是开始运行python-script时执行的第一个代码。其他模块可能不希望在程序运行期间在某处对answer of mine进行操作,因此其他模块(例如import sys
import importlib
from importlib.machinery import FileFinder, ExtensionFileLoader
# pick right loader for .dylib-files:
dylib_extension = ExtensionFileLoader, ['.dylib']
# add dylib-support to file-extension supported per default
all_supported_loaders = [dylib_extension]+ importlib._bootstrap_external._get_supported_file_loaders()
# replace the last hook (i.e. FileFinder) with one recognizing `.dylib` as well:
sys.path_hooks.pop()
sys.path_hooks.append(FileFinder.path_hook(*all_supported_loaders))
#and now import name.dylib via
import name
,sys.path_hooks
等)可能会出现一些问题。例如:
pdb
将失败,同时
traceback
将起作用,因为import pdb
#above code
import name
似乎操纵了进口机器。
通常,#above code
import pdb
import name
钩子是pdb
中的最后一个钩子,因为它是最后的手段,一旦为路径调用FileFinder
,就返回查找器(如果sys.path_hooks
应该查看更多的挂钩):
path_hook_for_FileFinder
但是,可能需要确定并检查,确实右钩已被更换。
更简单的选择是使用path_hook_for_FileFinder
(忽略ImportError
的描述):
PathFinder
[这可能比第一个解决方案更强大(例如def path_hook_for_FileFinder(path):
"""Path hook for importlib.machinery.FileFinder."""
if not _path_isdir(path):
raise ImportError('only directories are supported', path=path)
return cls(path, *loader_details) # HERE Finder is returned!
没有问题,但对大型项目而言不太方便。