runpy — Нахождение и выполнение модулей Python

Источник: Lib/runpy.py


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

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

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

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

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

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

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

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

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

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

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

__file__, __cached__, __loader__ и __package__ - set as normal в соответствии со спецификацией модуля.

Если аргумент 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.

Изменено в версии 3.12: Значения __cached__, __loader__ и __package__ устарели. Альтернативные варианты см. в ModuleSpec.

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

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

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

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

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

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

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

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

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

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

См.также

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

Added in version 3.2.

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

Изменено в версии 3.12: Значения __cached__, __loader__ и __package__ устарели.

См.также

PEP 338 – Выполнение модулей как скриптов

PEP написан и реализован Ником Когланом.

PEP 366 – Явный относительный импорт главного модуля

PEP написан и реализован Ником Когланом.

PEP 451 – Тип ModuleSpec для системы импорта

PEP написан и реализован Эриком Сноу

Командная строка и окружение - Детали командной строки CPython

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