31.4. runpy – Поиск и выполнение модулей Python¶runpy – 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__, __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()