runpy — Поиск и выполнение Python модулей


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

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

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

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

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

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

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

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

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

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

__spec__ будет установлен соответствующим образом для фактически импортированного модуля (то есть __spec__.name всегда будет mod_name или mod_name + '.__main__, а не run_name).

__file__, __cached__, __loader__ и __package__установлены как обычно в зависимости от спецификации модуля.

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

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

См.также

Опция -m, предлагающая эквивалентную функциональность из командной строки.

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

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

Изменено в версии 3.4: Обновлен, чтобы воспользоваться преимуществами спецификации модуля, добавленной PEP 451. Это позволяет правильно установить __cached__ для модулей, работающих таким образом, а также гарантировать, что настоящее имя модуля всегда доступно как __spec__.name.

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__, __spec__, __file__, __cached__, __loader__ и __package__ устанавливаются в глобальном словаре до выполнения кода модуля (обратите внимание, что это минимальный набор переменных — другие переменные могут быть заданы неявно как деталь реализации интерпретатора).

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

Если предоставленный путь напрямую ссылается на файл сценария (будь то исходный или предварительно скомпилированный байтовый код), то __file__ будет установлен на указанный путь, а __spec__, __cached__, __loader__ и __package__ будут установлены в None.

Если предоставленный путь является ссылкой на допустимую запись sys.path, то __spec__ будет установлен соответствующим образом для импортированного __main__ модуля (т. е. __spec__.name всегда будет __main__). __file__, __cached__, __loader__ и __package__ будут установлены как обычно в зависимости от спецификации модуля.

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

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

См.также

Интерфейсные опции для эквивалентной функциональности в командной строке (python path/to/script).

Добавлено в версии 3.2.

Изменено в версии 3.4: Обновлен, чтобы воспользоваться функцией спецификации модуля, добавленной PEP 451. Это позволяет правильно установить __cached__ в случае, когда __main__ импортируется из допустимой записи sys.path, а не выполняется напрямую.

См.также

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

Командная строка и окружение — CPython сведения командной строки.

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