FWIW, мне не удалось найти ссылку, утверждающую, что расширения должны быть загружены перед py-файлами, поэтому, вероятно, безопаснее рассматривать это как деталь реализации (если кто-то не предоставит ссылку). Даже если эта информация стабильна для всех версий, по крайней мере, до 2.7.
Когда модуль импортируется, он сначала просматривается в кеше (т. Е. sys.modules
), и, если его еще нет, используются средства поиска из sys.meta_path
. Обычно sys.meta_path
состоит из BuiltinImporter
, FrozenImporter
и PathFinder
, где PathFinder
отвечает за поиск модулей на пути к диску / python.
PathFinder
предоставляет некоторые функции кэширования для ускорения поиска, но в основном делегирует поиск на перехватчиков с sys.path_hooks
- обзор можно найти, например, в PEP 302 .
Обычно sys.path_hooks
состоят из zipimporter
, которые делают возможным импорт сжатых файлов, и обернутыми FileFinder
, что является рабочей лошадкой всего импорт-машина.
FileFinder
опробует различные варианты (т. Е. .so
, .py
, .pyc
) в заданном порядке, который устанавливается _get_supported_file_loaders()
-методом :
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- и так / pyd-файлы находятся рядом друг с другом.