Вы смотрите на два совершенно разных источника информации: учебник и справочник по языку.
Раздел учебника Путь поиска модуля (кроме описания только по умолчанию)поведение) также описывает только то, что происходит, когда модуль фактически импортируется.
Если модуль уже находится в кеше, этот процесс не происходит.Это здесь не объясняется, поскольку это уже было рассмотрено в предыдущем разделе Подробнее о модулях :
Модуль может содержать как исполняемые операторы, так и определения функций.Эти операторы предназначены для инициализации модуля.Они выполняются только в первый раз, когда имя модуля встречается в операторе импорта.
...
Примечание. Из соображений эффективности каждый модуль импортируется только один раз за сеанс интерпретатора.
Это не объясняет механизм, с помощью которого это происходит, потому что это всего лишь учебник.
Между тем, в справочных документах для системы импорта, модуль Секция cache объясняет первое, что происходит с оператором import
.
Обратите внимание, что не совсем верно, что Python избегает выполнения операторов модуля, если модуль уже был импортирован, или что он импортируется только один раз для эффективности.Это является следствием того факта, что загрузчики по умолчанию помещают модуль в кэш sys.modules
.И если вы замените загрузчики или обезьяну на кеш после факта, модуль фактически будет импортирован и выполнен несколько раз.
Последующие разделы - начиная со следующего раздела, Искатели и загрузчики - аналогично описывают детали того, как модуль найден, более строго и более подробно, чем раздел «Путь поиска модуля» учебного пособия:
Python включает в себя ряд искателей и импортеров по умолчанию.Первый знает, как найти встроенные модули, а второй знает, как найти замороженные модули.Третий искатель по умолчанию ищет пути импорта для модулей.
Итак, еще раз, не точно истина, что интерпретатор сначала ищет встроенный модуль.Вместо этого интерпретатор просто ищет свои искатели по порядку, и по умолчанию первый искатель является искателем встроенного модуля.Но если вы измените список искателей, Python не будет сначала искать встроенные модули.
На самом деле, если вы распечатаете sys.meta_path
при установке CPython 3.7 по умолчанию, что вы 'Вы увидите:
<class '_frozen_importlib.BuiltinImporter'>
<class '_frozen_importlib.FrozenImporter'>
<class '_frozen_importlib_external.PathFinder'>
(В IPython, или если вы импортировали что-то вроде six
, которое помогает переименовывать модули, или если вы импортировали что-то вроде requests
, которое встраивает модули с поддержкой версий, выУ меня будет пара дополнительных искателей.)
Это BuiltinImporter
задокументировано в документации по importlib
.(Если вам интересно, почему он не называется BuiltinFinder
, то средство поиска, которое также имеет собственный загрузчик, называется импортером.) Что он на самом деле делает, так это просматривает sys.builtin_module_names
и вызывает специфичную для реализации функциючтобы справиться с чем-либо найденным там.
В CPython 3.6 (извиняюсь за переход между 3,6 и 3,7, но это не должно иметь значения…), специфичная для реализации функция, которую он вызывает, _imp.create_builtin
, и вы можете отследить вещи оттуда.
Но главное, на что нужно обратить внимание, это то, что не все в builtin_module_names
на самом деле «встроено» в том смысле, что оно предварительноимпортирован.Например, при обычной установке вы, вероятно, увидите там _ast
, но не sys.modules['_ast']
.
Так что функция create_builtin
(или, для другой реализации, все, что она использует для реализацииBuiltinImporter
) должен иметь возможность импортировать модули / dll / pyd / dylib, поставляемые с Python.