Команда python -m: исполнение модулей как скриптов

Раздел: Основы Python -> Основы

Основной метод: запуск модуля с флагом -m

Как выполнить модуль Python, указав его имя, а не путь к файлу?

Флаг -m позволяет запустить модуль как скрипт. Python ищет модуль в стандартных путях (sys.path) и выполняет его код, обычно содержащийся в блоке if __name__ == '__main__'. Синтаксис: python -m module_name [аргументы].

Пример:

python -m http.server 8000

How write python (как писать на python)

Эта команда запускает встроенный HTTP-сервер на порту 8000. Python находит модуль http.server и выполняет его как скрипт.

Шаги:

  • Python преобразует имя модуля в путь, заменяя точки на разделители (например, http.server -> http/server.py).
  • Модуль ищется в директориях из sys.path (включая текущую рабочую директорию, если скрипт запущен из неё).
  • Найденный файл выполняется. Если модуль имеет пакетную структуру (папка с __init__.py), выполняется __main__.py внутри пакета.

Возможные проблемы:

  • ModuleNotFoundError: модуль не установлен или не находится в путях поиска. Решение: установить модуль (например, pip install module) или добавить путь в переменную окружения PYTHONPATH.
  • Конфликт имён: если есть локальный файл с именем, совпадающим со стандартным модулем. Решение: переименовать локальный файл или использовать абсолютный импорт.
  • Неверный синтаксис: забыли указать имя модуля после -m. Решение: проверить команду.

Вариант 1: прямой запуск файла (python script.py)

Как запустить скрипт, если он не является модулем и не требует поиска по sys.path?

Простой запуск python script.py сразу выполняет код файла. Отличие от -m: Python не добавляет директорию скрипта в sys.path автоматически, а добавляет директорию, в которой находится скрипт. Это может вызвать проблемы с импортами, если скрипт использует относительные импорты или зависит от структуры пакета.

Пример:

python my_script.py arg1 arg2

Python m команда (запуск модуля python с флагом -m)

Проблема: если скрипт находится внутри пакета и пытается импортировать соседние модули с помощью относительного импорта, возникнет ошибка. Решение: использовать запуск через -m, указав полное имя модуля, или настроить PYTHONPATH.

Вариант 2: импорт и вызов в другом скрипте

Как выполнить код модуля, не делая его исполняемым, а импортируя и вызывая функции?

Если модуль содержит функцию main(), её можно вызвать из другого скрипта:

import module\nmodule.main()
Этот подход подходит для библиотек. Он не требует наличия блока if __name__, но при импорте выполняется весь код верхнего уровня модуля, что может быть нежелательно.

Проблема: если модуль при импорте выводит сообщения или запускает сервер, это произойдет сразу. Решение: обернуть исполняемый код в функцию и вызывать только при необходимости.

Вариант 3: создание собственного исполняемого модуля с __main__.py

Как сделать пакет, который можно запускать через python -m mypackage?

В пакете (папке с __init__.py) создайте файл __main__.py. При запуске python -m mypackage Python выполнит именно его. Это удобно для создания CLI-инструментов.

Пример:


# mypackage/__main__.py
def main():
    print("Запущен пакет mypackage")
if __name__ == '__main__':
    main()
Команда: python -m mypackage

Проблема: если в пакете нет __main__.py, но есть __init__.py, Python выполнит __init__.py, что может не соответствовать ожиданиям. Решение: всегда создавать __main__.py для явного указания точки входа.

Практические примеры использования флага -m

Рассмотрим различные сценарии, где -m упрощает запуск.

Пример
# Пример 1: Установка пакета через pip как модуль
python -m pip install requests
# Результат: установка пакета requests (вывод скрыт)
Пример
# Пример 2: Создание виртуального окружения
python -m venv myenv
# Результат: создана папка myenv с изолированным интерпретатором
Пример
# Пример 3: Запуск встроенного отладчика pdb
python -m pdb my_script.py
# Результат: открывается интерактивная отладка, точки останова, пошаговое выполнение
Пример
# Пример 4: Профилирование кода cProfile
python -m cProfile -s cumtime my_script.py
# Результат: вывод статистики времени выполнения функций
Пример
# Пример 5: Запуск тестов unittest
python -m unittest discover -v tests/
# Результат: запуск всех тестов в папке tests с подробным выводом
Пример
# Пример 6: Запуск подмодуля внутри пакета (например, email.mime)
python -m email.mime.text
# Результат: ошибка? Нет, этот модуль не имеет __main__. Будет ошибка. Но можно использовать для проверки импорта.
Пример
# Пример 7: Использование -m с собственным пакетом
# Допустим, есть пакет myapp с файлом __main__.py, содержащим:
if __name__ == '__main__':
    print('Hello from myapp')
# Запуск:
python -m myapp
Hello from myapp
Пример
# Пример 8: Комбинирование -m с аргументами (передача скрипту)
python -m http.server 8000 --bind 127.0.0.1
# Сервер запускается на localhost:8000
Пример
# Пример 9: Запуск модуля, расположенного в текущей папке, если он не установлен
# Создайте файл mymodule.py с кодом:
def myfunc():
    print('Функция запущена как модуль')
if __name__ == '__main__':
    myfunc()
# Запуск:
python -m mymodule
Функция запущена как модуль
Пример
# Пример 10: Использование -m для запуска модуля из пакета, которого нет в sys.path
# Если модуль лежит в /home/user/mypackage, нужно добавить путь:
export PYTHONPATH=/home/user
python -m mypackage
# Результат: выполнится __main__.py в mypackage

Пояснение: Флаг -m особенно полезен для встроенных модулей (http.server, pdb, cProfile, unittest, venv, pip), так как они не требуют указания полного пути. Для собственных модулей нужно убедиться, что они доступны в sys.path. В большинстве случаев достаточно находиться в той же директории, что и модуль, или установить его через pip install -e .

Запуск модуля Python с флагом -m - comments

En
Python m команда (python)