← Назад к вопросам

Что такое флаг -m в Python?

1.6 Junior🔥 61 комментариев
#Django#Брокеры сообщений

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Флаг -m в Python

Флаг -m — это опция интерпретатора Python, которая позволяет запускать модули как скрипты. Она ищет модуль в sys.path и выполняет его как главную программу (__name__ == "__main__").

Синтаксис

python -m module_name [arguments]
python3 -m module_name [arguments]

Основное назначение

Без -m:

python /path/to/script.py arg1 arg2
# Запускает файл по абсолютному пути

С -m:

python -m mymodule arg1 arg2
# Ищет mymodule в путях и запускает его

Преимущества флага -m

1. Независимость от пути

# Без -m (зависит от текущей директории)
python src/myapp/main.py  # Нужно знать путь

# С -m (работает из любого места)
python -m myapp.main      # Модуль найдётся в sys.path

2. Правильное разрешение импортов

# src/myapp/__init__.py
print("Init myapp")

# src/myapp/main.py
import myapp  # Работает с -m, может не работать без неё
from myapp.utils import helper

if __name__ == "__main__":
    print("Main")
# Без -m (может быть ошибка импорта)
cd src
python myapp/main.py  # ошибка: ModuleNotFoundError

# С -m (всё работает)
python -m myapp.main  # OK: найдёт myapp в sys.path

Примеры использования

1. Запуск модуля как скрипта

# calculator.py
def add(a, b):
    return a + b

if __name__ == "__main__":
    import sys
    if len(sys.argv) == 3:
        a = int(sys.argv[1])
        b = int(sys.argv[2])
        print(f"{a} + {b} = {add(a, b)}")
    else:
        print("Использование: python calculator.py a b")
python -m calculator 5 3
# Вывод: 5 + 3 = 8

2. Запуск пакета (package)

# myapp/__init__.py
print("Инициализация myapp")

# myapp/__main__.py
print("Запуск myapp")
print(f"__name__ = {__name__}")
python -m myapp
# Вывод:
# Инициализация myapp
# Запуск myapp
# __name__ = __main__

3. Встроенные модули Python

# HTTP сервер
python -m http.server 8000
# Запускает сервер на localhost:8000

# JSON валидация
echo '{"key": "value"}' | python -m json.tool
# Красиво форматирует JSON

# Модуль zipfile
python -m zipfile -l archive.zip
# Список файлов в архиве

# HTTP запросы
python -m http.client
# Интерактивный HTTP клиент

# unittest
python -m unittest discover -s tests
# Запускает все тесты в папке tests

Различие между способами запуска

Способ 1: Прямое выполнение файла

python path/to/script.py
  • __name__ = "__main__"
  • __file__ = "path/to/script.py"
  • Модуль НЕ добавляется в sys.modules
  • Импорты ищут в текущей директории

Способ 2: Запуск через -m

python -m mymodule
  • __name__ = "__main__"
  • __file__ = полный путь к модулю
  • Модуль добавляется в sys.modules
  • Импорты ищут в sys.path (как обычно)
  • Правильное разрешение относительных импортов

Практический пример: Django

# Django использует -m для manage.py
python -m django startproject mysite
python -m django startapp myapp

# Или через manage.py (который использует -m внутри)
python manage.py runserver
python manage.py migrate
python manage.py createsuperuser

Запуск пакета как основной программы

# myapp/
#   __init__.py
#   __main__.py  <- КЛЮЧ!
#   cli.py
#   utils.py

# myapp/__main__.py
import sys
from myapp.cli import main

if __name__ == "__main__":
    main(sys.argv[1:])
# Теперь пакет можно запустить как программу
python -m myapp arg1 arg2
# Сначала выполняется myapp/__init__.py
# Затем выполняется myapp/__main__.py

Флаги -m с другими опциями

-u (unbuffered)

# Вывод без буферизации (для логирования)
python -u -m myapp

-i (интерактивный режим после выполнения)

# После выполнения модуля запустить интерпретатор
python -i -m myapp

-v (verbose)

# Показать все импорты
python -v -m myapp

-c (код как аргумент)

# Запустить код и затем модуль
python -c "import os; print(os.getcwd())" -m myapp

sys.path и -m

# myscript.py
import sys
print("sys.path:")
for path in sys.path:
    print(f"  {path}")
# Без -m
python myscript.py
# sys.path содержит текущую директорию

# С -m
python -m myscript
# sys.path содержит текущую директорию вверху

Установка пакета с entry points

# setup.py
from setuptools import setup

setup(
    name="myapp",
    version="1.0",
    packages=["myapp"],
    entry_points={
        "console_scripts": [
            "myapp=myapp.cli:main",
        ]
    }
)
# После установки (pip install -e .)
myapp arg1 arg2  # Прямой вызов команды

# Или через -m
python -m myapp arg1 arg2

Полный пример: CLI приложение

# myapp/__init__.py
__version__ = "1.0.0"

# myapp/__main__.py
import sys
import argparse
from myapp import __version__
from myapp.commands import run, serve

def main(args=None):
    parser = argparse.ArgumentParser(
        description="MyApp - полезное приложение"
    )
    parser.add_argument(
        "--version", 
        action="version", 
        version=f"%(prog)s {__version__}"
    )
    
    subparsers = parser.add_subparsers(dest="command")
    
    # Команда run
    run_parser = subparsers.add_parser("run", help="Запустить приложение")
    run_parser.add_argument("--debug", action="store_true")
    
    # Команда serve
    serve_parser = subparsers.add_parser("serve", help="Запустить сервер")
    serve_parser.add_argument("--port", type=int, default=8000)
    
    parsed_args = parser.parse_args(args)
    
    if parsed_args.command == "run":
        run(debug=parsed_args.debug)
    elif parsed_args.command == "serve":
        serve(port=parsed_args.port)
    else:
        parser.print_help()

if __name__ == "__main__":
    main()

# myapp/commands.py
def run(debug=False):
    print(f"Запуск приложения (debug={debug})")

def serve(port=8000):
    print(f"Запуск сервера на порту {port}")
# Использование
python -m myapp run --debug
# Вывод: Запуск приложения (debug=True)

python -m myapp serve --port 9000
# Вывод: Запуск сервера на порту 9000

python -m myapp --version
# Вывод: __main__.py 1.0.0

Лучшие практики

  1. Используй -m для пакетов: правильное разрешение импортов
  2. Создавай main.py: стандартный способ запуска пакета
  3. Тестируй с -m: убедись, что всё работает со своим путём
  4. Документируй использование: покажи как запускается твоё приложение

Флаг -m — это стандартный способ запуска модулей и пакетов в Python, обеспечивающий правильное разрешение импортов и независимость от текущей директории.