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

时间:2019-05-06 12:06:57

标签: python python-import python-extensions

通过实验,我验证了当编译的extension.pyd(或.so)和普通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文件添加逻辑吗? / p>

1 个答案:

答案 0 :(得分:2)

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

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

sys.path_hooks提供了一些缓存功能以加快查找速度,但从delegates the searchhookssys.path_hooks基本上是这样-例如,在PEP 302

通常,zipimporterFileFinder组成,这使得压缩文件的导入成为可能,and是经过包装的FileFinder,这是整个导入的主要动力,机械。

.so按给定顺序尝试不同的满足条件(即.py.pycdef _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] ),该顺序由_get_supported_file_loaders()-method建立:

sys.meta_path

可以看到:

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

很显然,sys.path_hooks public function login($email, $password, $remember){ $this->db->query('SELECT * FROM users WHERE email = :email'); $this->db->bind('email', $email); $row = $this->db->single(); $password_hash = $row->password; if(password_verify($password, $password_hash)) { if($remember){ setcookie('email', $email, time() + 86400); } return $row; }else{ return false; } } 都可以通过某种方式进行操纵,该方式可以建立任意顺序的装入首选项。

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