我在同一目录中有2个文件,一个编译的库文件和一个源文件:
.
├── a.py
└── a.pyd
看起来像
import a
实际导入了a.pyd
模块。但是我找不到保证这一点的官方文件。有谁知道不同文件类型的导入顺序吗?
同样的问题适用于Unix Python扩展名(.so)
最佳答案
在典型的Python安装中, ExtensionFileLoader
类的优先级高于用于SourceFileLoader
文件的 .py
。它是ExtensionFileLoader
来处理.pyd
文件的导入,在Windows机器上,您会发现 .pyd
已在here in importlib.machinery.EXTENSION_SUFFIXES
中注册了.so
(注意:在Linux/macOS上,它将在其中包含sys.path
)。
因此,在同一目录内发生名称冲突的情况下(按顺序浏览a.pyd
时表示“领带”),a.py
文件优先于a.pyd
文件。您可以验证是否在创建空的a.py
和import a
文件时,语句importlib._bootstrap_external. _get_supported_file_loaders
尝试加载DLL(当然会失败)。
要查看CPython源代码中的优先级,请查看http://www.python.org/doc/essays/packages/:
def _get_supported_file_loaders():
"""Returns a list of file-based module loaders.
Each item is a tuple (loader, suffixes).
"""
extensions = ExtensionFileLoader, _imp.extension_suffixes()
source = SourceFileLoader, SOURCE_SUFFIXES
bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES
return [extensions, source, bytecode] # <-- extensions before source!
有关文档引用,请参见
'.pyd'
该文档未明确提及“.pyd”,但在Windows中等效于“.so”。我刚刚在Windows机器上进行了测试,确实
'.py'
在后缀列表中的sys.meta_path
之前出现。请注意,上面给出的引用文献很旧!自从撰写本文以来,导入系统已被完全改造,并且为用户提供了底层的机制(例如,您可以更改ojit_a来注册自己的加载程序或更改优先级)。因此,现在可以自定义“.py”而不是“.pyd”,而且
imp.get_suffixes()
对任何内容说什么都无关紧要(实际上,该功能现在已被弃用)。当然,默认的Python安装不会这样做,并且默认优先级与上面提到的引用相同。关于python - "import"喜欢什么-.pyd(.so)或.py?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58686448/