Argparse в Python: аргументы командной строки и проверка ввода

Argparse в Python: аргументы командной строки и проверка ввода
Содержание статьи

Модуль argparse разбирает аргументы командной строки, формирует справку и сообщает об ошибках ввода. Описание интерфейса лучше отделить от основной функции программы: тогда одни и те же правила можно проверить на списке аргументов без запуска отдельного процесса.

В примере Mentoring.digital сделаем безопасный интерфейс утилиты отчётов. Она только показывает разобранные параметры. Создание файлов и обработку отчётов добавляют отдельно.

Создайте parser с явным контрактом

Сохраните код в report_cli.py. Пример подходит для Python 3.10 и новее. Позиционный аргумент задаёт тему, --limit принимает положительное целое число, --format ограничен двумя вариантами, --verbose работает как переключатель.

import argparse

def positive_int(value):
    try:
        number = int(value)
    except ValueError:
        raise argparse.ArgumentTypeError("нужно целое число")
    if number <= 0:
        raise argparse.ArgumentTypeError("число должно быть больше нуля")
    return number

def build_parser():
    parser = argparse.ArgumentParser(
        description="Параметры учебного отчёта",
        allow_abbrev=False,
    )
    parser.add_argument("topic", help="тема отчёта")
    parser.add_argument("--limit", type=positive_int, default=10,
                        help="число строк, по умолчанию 10")
    parser.add_argument("--format", choices=("text", "json"),
                        default="text")
    parser.add_argument("--verbose", action="store_true")
    return parser

def main(argv=None):
    args = build_parser().parse_args(argv)
    print(vars(args))

if __name__ == "__main__":
    main()

allow_abbrev=False запрещает сокращённые длинные опции. Это делает интерфейс предсказуемее при добавлении новых флагов: пользователь передаёт --limit, а не случайно подходящее --li. Справка -h и --help создаётся автоматически.

Проверьте обычный запуск и ошибки

python report_cli.py "Продажи за месяц" --limit 3 --format json --verbose
python report_cli.py --help
python report_cli.py test --limit 0
python report_cli.py test --format xml

В первом запуске topic будет строкой, limit целым числом 3, format строкой json, verbose значением True. Кавычки сохраняют тему с пробелами как один аргумент. В двух последних командах parser должен завершиться с сообщением об ошибке, не переходя к полезной работе.

Не используйте type=bool для флага. Строка «False» непустая, поэтому bool('False') даёт True. Для переключателя без значения подходит store_true. Если интерфейс требует пару --feature и --no-feature, отдельно рассмотрите BooleanOptionalAction.

Проверяйте parser на готовом списке

parser = build_parser()
args = parser.parse_args(["test", "--limit", "2"])
assert args.limit == 2
assert args.verbose is False

try:
    parser.parse_args(["test", "--limit", "-1"])
except SystemExit as error:
    assert error.code == 2
else:
    raise AssertionError("Отрицательное значение принято")

Здесь SystemExit перехватывается для проверки поведения в тесте. В обычной утилите не нужно гасить все исключения и продолжать работу с некорректными параметрами. Дополнительно проверьте отсутствие topic, неизвестный флаг, нечисловой limit и регистр значения JSON: choices в этом примере чувствителен к регистру.

Где заканчивается разбор аргументов

Успешный parse_args не доказывает существование файла, доступность сервера или право на запись. Такие проверки выполняются на соответствующем шаге программы. Не передавайте введённые строки в оболочку через склеенную команду. Не помещайте пароли в аргументы: они могут попасть в историю команд и список процессов.

Разработку небольших утилит можно разобрать на занятиях по Python. Для проверки интерфейса своего скрипта выберите ментора по Python и принесите примеры корректных и ошибочных запусков.

Похожие статьи по данной теме