Документация Python неофициальный перевод

29.5. runpy – Поиск и выполнение модулей Pythonrunpy – Locating and executing Python modules

Исходный код: Lib/runpy.py


Модуль runpy используется для поиска и запуска модулей Python без их предварительного импорта. Его основное назначение – реализация ключа командной строки -m, который позволяет находить скрипты с использованием пространства имён модулей Python вместо файловой системы.

Обратите внимание: это не изолированный модуль – весь код выполняется в текущем процессе, и все побочные эффекты (например, кешированные импорты других модулей) сохраняются после возврата из функций.

Кроме того, любые функции и классы, определённые в выполняемом коде, не гарантируют корректную работу после возврата из функции runpy. Если такое ограничение неприемлемо для конкретного случая использования, importlib, скорее всего, будет более подходящим выбором, чем этот модуль.

Модуль runpy предоставляет две функции:

runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)

Выполняет код указанного модуля и возвращает результирующий словарь глобальных переменных модуля. Сначала код модуля находится с помощью стандартного механизма импорта (подробнее см. PEP 302), а затем выполняется в новом пространстве имён модуля.

Если указанное имя модуля ссылается на пакет, а не на обычный модуль, то этот пакет импортируется, и выполняется подмодуль __main__ внутри этого пакета, после чего возвращается результирующий словарь глобалов модуля.

Необязательный аргумент-словарь init_globals можно использовать для предварительного заполнения словаря глобалов модуля до выполнения кода. Переданный словарь не будет изменён. Если какие-либо из специальных глобальных переменных, перечисленных ниже, определены в переданном словаре, эти определения переопределяются функцией run_module().

Специальные глобальные переменные __name__, __file__, __cached__, __loader__ и __package__ устанавливаются в словаре глобальных переменных перед выполнением кода модуля (обратите внимание, что это минимальный набор переменных – остальные могут быть установлены неявно как деталь реализации интерпретатора).

__name__ устанавливается в значение run_name, если этот необязательный аргумент не равен None; в mod_name + '.__main__', если указанный модуль является пакетом; и в значение аргумента mod_name в противном случае.

__file__ устанавливается в имя, предоставленное загрузчиком модуля. Если загрузчик не предоставляет информацию об имени файла, эта переменная устанавливается в None.

__cached__ будет установлена в None.

__loader__ устанавливается в загрузчик модуля PEP 302, используемый для получения кода модуля (этот загрузчик может быть обёрткой вокруг стандартного механизма импорта).

__package__ устанавливается в mod_name, если именованный модуль является пакетом, и в mod_name.rpartition('.')[0] в противном случае.

Если аргумент alter_sys передан и равен True, то sys.argv[0] обновляется значением __file__, а sys.modules[__name__] – временным объектом модуля для выполняемого модуля. Как sys.argv[0], так и sys.modules[__name__] восстанавливаются до исходных значений перед возвратом функции.

Обратите внимание, что такое манипулирование sys не является потокобезопасным. Другие потоки могут видеть частично инициализированный модуль, а также изменённый список аргументов. Рекомендуется не трогать модуль sys при вызове этой функции из многопоточного кода.

Изменено в версии 3.1: добавлена возможность выполнения пакетов путём поиска подмодуля __main__.

Изменено в версии 3.2: добавлена глобальная переменная __cached__ (см. PEP 3147).

runpy.run_path(file_path, init_globals=None, run_name=None)

Выполняет код по указанному пути в файловой системе и возвращает результирующий словарь глобалов модуля. Как и имя скрипта, переданное в командной строке CPython, указанный путь может ссылаться на исходный файл Python, скомпилированный байт-код или запись sys.path, содержащую модуль __main__ (например, zip-файл, содержащий файл __main__.py верхнего уровня).

Для простого скрипта указанный код просто выполняется в новом пространстве имён модуля. Для корректной записи sys.path (обычно zip-файл или каталог) запись сначала добавляется в начало sys.path. Затем функция ищет и выполняет модуль __main__ с использованием обновлённого пути. Обратите внимание, что нет специальной защиты от вызова существующей записи __main__, расположенной в другом месте sys.path, если такой модуль отсутствует по указанному пути.

Необязательный аргумент-словарь init_globals можно использовать для предварительного заполнения словаря глобалов модуля до выполнения кода. Переданный словарь не будет изменён. Если какие-либо из специальных глобальных переменных, перечисленных ниже, определены в переданном словаре, эти определения переопределяются функцией run_path().

Специальные глобальные переменные __name__, __file__, __loader__ и __package__ устанавливаются в словаре глобальных переменных перед выполнением кода модуля (обратите внимание, что это минимальный набор переменных – остальные могут быть установлены неявно как деталь реализации интерпретатора).

__name__ устанавливается в значение run_name, если этот необязательный аргумент не равен None, и в '<run_path>' в противном случае.

__file__ устанавливается в имя, предоставленное загрузчиком модуля. Если загрузчик не предоставляет информацию об имени файла, эта переменная устанавливается в None. Для простого скрипта она будет установлена в file_path.

__loader__ устанавливается в загрузчик модуля PEP 302, используемый для получения кода модуля (этот загрузчик может быть обёрткой вокруг стандартного механизма импорта). Для простого скрипта он будет установлен в None.

__package__ устанавливается в __name__.rpartition('.')[0].

Также в модуль sys вносится ряд изменений. Во-первых, sys.path может быть изменён, как описано выше. sys.argv[0] обновляется значением file_path, а sys.modules[__name__] обновляется временным объектом модуля для выполняемого модуля. Все изменения элементов в sys отменяются перед возвратом функции.

Обратите внимание, что, в отличие от run_module(), изменения, вносимые в sys, не являются необязательными в этой функции, поскольку эти корректировки необходимы для разрешения выполнения записей sys.path. Поскольку ограничения потокобезопасности по-прежнему действуют, использование этой функции в многопоточном коде должно быть либо сериализовано с помощью блокировки импорта, либо делегировано отдельному процессу.

Новое в версии 3.2.

См. также

PEP 338 – Выполнение модулей как сценариев
PEP написан и реализован Ником Когланом.
PEP 366 – Явные относительные импорты главного модуля
PEP написан и реализован Ником Когланом.

Командная строка и окружение – подробности о командной строке CPython

Функция importlib.import_module()