argparse в Python: простое руководство с примерами и лучшими практиками

argparse в Python: простое руководство с примерами и лучшими практиками

argparse в Python: простое руководство с примерами и лучшими практиками

Если вы пишете скрипты и хотите запускать их с параметрами вроде -v или —output=data.json, вам нужен argparse. Это модуль стандартной библиотеки Python, который превращает ваши скрипты в удобные утилиты с автогенерируемой справкой и валидацией аргументов.

Быстрый старт

Создадим простой скрипт, который приветствует пользователя несколько раз и поддерживает флаг подробного вывода.

# hello.py
import argparse

parser = argparse.ArgumentParser(description="Приветствие пользователя")
parser.add_argument("name", help="Имя пользователя")
parser.add_argument("-c", "--count", type=int, default=1, help="Сколько раз поприветствовать")
parser.add_argument("-v", "--verbose", action="store_true", help="Подробный вывод")

args = parser.parse_args()

for i in range(args.count):
    msg = f"Привет, {args.name}!"
    if args.verbose:
        msg = f"[{i+1}/{args.count}] " + msg
    print(msg)
# Примеры запуска
python hello.py Алиса
python hello.py Алиса -c 3 --verbose
python hello.py -h  # автогенерируемая помощь

Позиционные и опциональные аргументы

  • Позиционные — без дефисов, обязательны: name
  • Опциональные — начинаются с — или —: -c, —verbose
  • Часто достаточно указать type, default и help, чтобы получить удобный интерфейс и понятные ошибки парсинга.

    Типы, проверки и значения по умолчанию

    Вы можете валидировать вход с помощью готовых типов (int, float) или собственных функций, выбрасывающих argparse.ArgumentTypeError.

    import argparse
    
    def positive_int(value: str) -> int:
        try:
            ivalue = int(value)
        except ValueError:
            raise argparse.ArgumentTypeError("Ожидалось целое число")
        if ivalue <= 0:
            raise argparse.ArgumentTypeError("Число должно быть > 0")
        return ivalue
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--retries", type=positive_int, default=3, help="Количество повторов > 0")
    args = parser.parse_args()
    print(args.retries)
    

    choices, metavar и наглядная справка

    Чтобы ограничить значения и улучшить помощь, используйте choices и metavar.

    import argparse, json
    
    parser = argparse.ArgumentParser(description="Форматированный вывод")
    parser.add_argument("message", help="Текст сообщения")
    parser.add_argument("-f", "--format", choices=["text", "json"], default="text",
                        help="Формат вывода")
    parser.add_argument("-o", "--output", metavar="FILE", help="Файл для записи результата")
    args = parser.parse_args()
    
    result = args.message if args.format == "text" else json.dumps({"message": args.message}, ensure_ascii=False)
    
    if args.output:
        with open(args.output, "w", encoding="utf-8") as f:
            f.write(result + "n")
    else:
        print(result)
    

    Взаимно исключающие аргументы

    Нужно разрешить только один из флагов? Используйте add_mutually_exclusive_group.

    import argparse
    
    parser = argparse.ArgumentParser(description="Изменение регистра")
    parser.add_argument("text")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--upper", action="store_true", help="Преобразовать в ВЕРХНИЙ регистр")
    group.add_argument("--lower", action="store_true", help="Преобразовать в нижний регистр")
    args = parser.parse_args()
    
    print(args.text.upper() if args.upper else args.text.lower())
    

    Подкоманды (как в git): subparsers

    Подкоманды позволяют строить богаче структуру CLI, например: tool sum … и tool mul …

    # calc.py
    import argparse
    from functools import reduce
    import operator as op
    
    parser = argparse.ArgumentParser(prog="calc", description="Простая калькуляция")
    subparsers = parser.add_subparsers(dest="command", required=True)
    
    sum_p = subparsers.add_parser("sum", help="Сумма чисел")
    sum_p.add_argument("nums", nargs="+", type=float, help="Слагаемые")
    
    mul_p = subparsers.add_parser("mul", help="Произведение чисел")
    mul_p.add_argument("nums", nargs="+", type=float, help="Множители")
    
    args = parser.parse_args()
    
    if args.command == "sum":
        print(sum(args.nums))
    elif args.command == "mul":
        print(reduce(op.mul, args.nums, 1.0))
    
    python calc.py sum 1 2 3
    python calc.py mul 2 5 10
    python calc.py -h
    python calc.py sum -h
    

    Флаги и режимы: action

    Помимо store_true существуют и другие действия: count, append и т. п.

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--verbose", action="count", default=0,
                        help="Уровень подробности: -v, -vv, -vvv")
    parser.add_argument("-t", "--tag", action="append", help="Можно указать несколько тегов")
    args = parser.parse_args()
    print(args.verbose, args.tag)
    

    Значения из окружения

    Удобно подставлять дефолты из переменных окружения, не ломая UX.

    import argparse, os
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--api-key", default=os.getenv("API_KEY"),
                        help="Ключ API (по умолчанию из переменной окружения API_KEY)")
    args = parser.parse_args()
    print("API_KEY:", args.api_key)
    

    Разбор неизвестных аргументов

    Иногда часть параметров вы хотите передать дальше. Поможет parse_known_args.

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--mode", choices=["fast", "safe"], default="safe")
    args, rest = parser.parse_known_args()
    print("mode=", args.mode, "rest=", rest)
    

    Тестирование CLI

    Проверьте, что справка и ошибки формируются корректно. Простейший путь — вызывать скрипт через subprocess.

    import subprocess, sys
    
    result = subprocess.run([sys.executable, "hello.py", "-h"], capture_output=True, text=True)
    assert "usage:" in result.stdout
    

    Типичные ошибки и как их избежать

  • Не делайте опции обязательными без необходимости. Если опция нужна всегда — подумайте, не сделать ли её позиционной.
  • Пишите понятные help и description — это ваша встроенная документация.
  • Используйте choices и кастомные type для ранней валидации входа.
  • Добавляйте подкоманды, если логика ветвится; не захламляйте один парсер десятками опций.
  • Для уровней логирования применяйте -v/-vv и action=»count» — это удобный де‑факто стандарт.
  • Мини‑шпаргалка по argparse

  • Обязательный позиционный: parser.add_argument(«path»)
  • Опция с типом и дефолтом: parser.add_argument(«-n», «—num», type=int, default=1)
  • Булев флаг: parser.add_argument(«-q», «—quiet», action=»store_true»)
  • Группа: group = parser.add_mutually_exclusive_group(required=True)
  • Подкоманды: subparsers = parser.add_subparsers(dest=»cmd», required=True)
  • Неизвестные опции: args, rest = parser.parse_known_args()
  • Где идти дальше

    Освоив argparse, вы сможете быстро собирать удобные утилиты для автоматизации. Если хотите прокачать весь фундамент Python — синтаксис, коллекции, ООП, работу с файлами, сетью и тестированием — рекомендую пройти путь от нуля до уверенного уровня на курсе «Программирование на Python с Нуля до Гуру».

    Вывод

    argparse в Python позволяет создавать дружелюбные к пользователю CLI: валидирует ввод, генерирует справку и масштабируется под сложные сценарии с подкомандами. Начните с базового парсера, добавляйте флаги и проверки по мере роста требований — и ваш скрипт станет профессиональной утилитой.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий