Python中是否可以保证模块文件名中扩展名的导入顺序?

发布于 2021-01-29 15:04:29

通过实验,我验证了当同一目录中同时存在编译的extension.pyd(或.so)和Plain时extension.py.pyd首先导入文件;的.py,如果只输入.pyd文件未找到:

In [1]: import extension

In [2]: extension.__file__
Out[2]: 'extension.pyd'

In [3]: import glob; glob.glob("extension.py*")
Out[3]: ['extension.py', 'extension.pyd']

是否保证所有版本的Python都相同,并且我可以依靠它向.py仅在.pyd未找到文件时执行的文件添加逻辑吗?

关注者
0
被浏览
56
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    FWIW,我找不到参考说明,必须在py文件之前加载扩展,因此将其作为实现细节可能更安全(除非有人提供参考)。即使此细节对于所有版本都稳定到至少2.7。

    导入模块时,它将首先在缓存中查找(即sys.modules),如果尚未在其中,sys.meta_path则使用from中的查找器。通常,sys.meta_pathBuiltinImporterFrozenImporter和组成PathFinder,其中PathFinder负责在磁盘/
    python-path上查找模块。

    PathFinder提供了一些缓存功能,以加速查找,但它基本上代表所述搜索sys.path_hooks-概述可以在例如发现PEP
    302

    通常情况下,sys.path_hooks包括zipimporter,这使压缩文件的导入可能,一个包裹
    FileFinder,这是整个进口机械的工作马。

    FileFinder尝试不同的出就足够了(即.so.py.pyc)在给定的顺序,这是通过建立_get_supported_file_loaders()-method

    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]
    

    可以看到:

    • 扩展名在源文件(即py文件)之前
    • 源文件先于pyc文件

    显然,sys.meta_path以及sys.path_hooks可以以某种方式进行操纵,这将建立负载优先级的任意顺序。

    作为个人说明:我将尽量避免py和so / pyd文件彼此相邻的情况。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看