Разбираемся, как это сделать. Библиотека argparse поможет принимать значение конфига в командной строке.
Вот вам четыре шага:
- Импортируйте библиотеку.
- Создайте парсер.
- Добавьте в него аргументы.
- Запустите .parse_args() .
Последний приведёт к объекту Namespace . Он содержит простое свойство для каждого входного аргумента из терминала.
Для подробного разбора этапов посмотрите программу myls.py . Она перечисляет файлы в текущей директории. Ниже – реализация без argparse :
Скрипт работает, но вывод отличается от встроенной команды.
Улучшите код с argparse :
Первое отличие – отсутствие условного оператора if , который проверял бы аргументы. Библиотека берёт эту функцию на себя.
Мы импортировали argparse , создали простой парсер с описанием программы и определили ожидаемые от пользователя аргументы. Последним делом запустили .parse_args() для разбора аргументов на входе и получения объекта Namespace , который содержит пользовательский ввод.
После запуска вы увидите, как всего четыре строчки меняют результат:
Отсутствует нужный аргумент пути, поэтому получим ошибку.
А также программа принимает флаг -h , как в примере ниже:
Приложение отвечает на -h выводом справки. И это не требует от нас никаких усилий!
Всего четыре строчки кода превратили переменную args в объект Namespace . Он содержит свойства для аргументов, которые юзер вводит в интерфейс командной строки.
Назовите программу
По умолчанию библиотека использует значение элемента sys.argv[0] для наименования программы, что соответствует названию скрипта. Укажите имя ключевым словом prog :
Оно будет отображаться в справке:
Теперь программа называется myls , а не myls.py .
Выводите настраиваемую справку в интерфейс командной строки
По умолчанию argparse создаёт помощь своего формата. Настройте её с помощью usage :
Во время выполнения токен %(prog)s автоматически заменяется именем программы:
И справка показывает другую строку использования, где опция -h сменилась универсальными токеном [options] .
Отображайте текст до и после аргументов справки
Используйте два ключевых слова для настройки текста до и после справки:
- description : описание до вывода помощи
- epilog : текст после
Посмотрим, как работает epilog :
Задайте символ префикса
По умолчанию, тире – начинает необязательные аргументы. Измените его с помощью ключевого слова prefix_chars :
Программа стала поддерживать другой префикс, а справка претерпела изменения:
Она отображается аргументом /h . Используйте это для разработки под Windows.
Символы префикса для файлов
Сохраняйте аргументы для сложных программ запуска в файле и загружайте из него. argparse выполняет эту работу из коробки.
Для теста напишите программу:
При создании парсера мы задействовали ключевое слово fromfile_prefix_chars .
Запуск без аргументов приведёт к ошибке:
Создайте args.txt с параметрами в каждой строке:
У вас есть специальный символ префикса для указания файла с аргументами. Откройте интерфейс командной строки и запустите предыдущую программу:
Видим: argparse считывает аргументы из файла args.txt .
Разрешайте и запрещайте сокращения
Следующая программа выводит указанное вами значение для аргумента –input :
Посмотрите, как argparse обрабатывает сокращения и вызывает программу несколько раз:
А что случится, если передать аргумент –i 42 ? Библиотека не сможет понять, передавать 42 аргументу –input или –id , и выведет сообщение об ошибке:
Не нравится эта функция? Хотите заставить пользователей вводить полные названия опций? Просто отключите эту возможность ключевым словом allow_abbrev со значением False на этапе создания парсера:
Запустите код, и вы увидите, что сокращения недоступны:
Ошибка сообщает, что пользователь не указал параметр –input потому, что программа не распознала сокращение –inp .
Задавайте имена флагов и аргументов
Вы можете добавить в интерфейс командной строки два типа аргументов:
- позиционные
- необязательные
Позиционными командами оперирует программа.
В предыдущем примере path – позиционный аргумент. Без него программа не работает. Они называются позиционными потому, что позиция определяет их функцию.
Рассмотрим cp из Linux:
Первый позиционный аргумент после cp – источник файла для копирования. Второй – место назначения копии.
Необязательные аргументы изменяют поведение команд во время выполнения. В примере с cp необязательный аргумент флаг -r заставляет команду копировать директории рекурсивно.
Два типа аргументов отличаются синтаксисом: необязательные начинаются с – или — .
Хотите добавить необязательный аргумент? Вызовите .add_argument() и назовите новый аргумент, начиная с – .
Запустите и проверьте опцию -l :
Теперь программа принимает, но не требует опцию -l .
Задайте действие для аргумента
При добавлении необязательного аргумента можно указать действие. Задайте способ хранения значения в объекте Namespace , который вы получите после выполнения .parse_args() .
Некоторые действия предопределены и доступны для использования:
- store хранит входное значение в объекте Namespace (действие по умолчанию).
- store_const содержит постоянное значение, когда указаны соответствующие необязательные аргументы.
- store_true хранит логическое True , когда указан соответствующий необязательный аргумент, и False в других случаях.
- store_false хранит логическое False , когда указан соответствующий необязательный аргумент, и True в других случаях.
- append содержит список, добавляя значение каждый раз, когда опция указана.
- append_const хранит список, добавляя постоянное значение.
- count хранит int , равный количеству использования опции.
- help выводит справку.
- version показывает версию программы.
Рассмотрим вышеуказанные опции на следующем примере:
Скрипт принимает необязательный аргумент для каждого типа действия выше и печатает значение аргументов, передаваемых через интерфейс командной строки. Протестируйте выполнением примера:
Видно, что без указаний аргументов, значения по умолчанию – None .
Действие store хранит передаваемое значение:
store_const хранит определённую константу, когда предоставлены аргументы. В тесте мы указали аргумент b , и значение args.b стало 42 :
Действие store_true хранит логическое True при наличии передаваемых аргументов и False в остальных случаях. Нужно противоположное поведение? Воспользуйтесь действием store_false :
Создавайте список всех переданных значений одним аргументом с помощью append :
append_const похоже на append , но добавляет одно постоянное значение:
count считает количество передач аргумента. Оно полезно в реализации уровня подробностей вывода программы. Можно определить уровень как -v – меньше подробностей, чем -vvv :
Действие version просто показывает версию программы:
Ещё одна возможность: создавайте собственные действия. Для этого наследуйте класс argparse.Action и реализуйте пару методов.
Следующий пример – настраиваемое действие store , которое выводит больше подробностей, чем стандартное:
Программа вывела линию прежде, чем задать значение 42 параметру -i .
Задавайте количество значений для опции
По умолчанию парсер предполагает один параметр для каждого аргумента. Измените это поведение, указав другое количество значений ключевым словом nargs .
Нужен аргумент, который принимает три значения? Укажите 3 в качестве значения nargs во время добавления параметра в парсер:
Теперь программа принимает три значения для параметра –input :
А значение переменной args.input – это список с тремя значениями.
Ключевое слово nargs также принимает:
- ? : одно необязательное значение;
- * : гибкое количество значений, которые собираются в список;
- + : похоже на * , но требует хотя бы одного значения;
- argparse.REMAINDER : все значения, которые остаются в командной строке.
В следующей программе позиционный аргумент input принимает одно значение. Если оно отсутствует, программа использует значение ключевого слово default :
Выбирайте значение для аргумента input . В данном случае будет использовано default :
Чтобы принять несколько значений и собрать их в список, укажите * в качестве значения nargs :
Этот код позволяет задавать гибкое число значений для ожидаемого аргумента:
Если вам нужно принять переменное количество значений и убедиться, что указано хотя бы одно значение, используйте + в качестве значений nargs :
Запустите программу без позиционных аргументов, и увидите точное сообщение об ошибке:
Напоследок представьте, что вам нужно захватить и отправить в список все оставшиеся аргументы, которые были указаны в командной строке. Для этого присвойте значение argparse.REMAINDER ключевому слову nargs :
Посмотрите, что происходит: первое значение будет связано с первым параметром. Остальные – со вторым:
Оставшиеся значения собираются в список.
Установите значение по умолчанию в отсутствии аргумента
Вы уже знаете, что пользователь может не указывать необязательные аргументы в командной строке. Когда аргументы не указаны, соответствующее значение ставится в None .
Но вы можете определить значение по умолчанию для аргумента:
Запустите программу без опции -a , и вы получите:
Теперь опция -a имеет значение 42 , хотя вы не указывали это явно в командной строке.
Установите тип аргумента
По умолчанию все входные значения обрабатываются как строки. У вас есть возможность определять тип соответствующего свойства объекта Namespace , которое вы получаете после вызова .parse_args() . Воспользуйтесь ключевым словом type :
Указывая значение типа int для аргумента, вы говорите argparse , что свойство .a объекта Namespace должно быть int вместо string :
Теперь значение аргумента проверяется во время выполнения. Если значение не подходит, выводится чёткая ошибка:
Установите допустимые значения для определённого аргумента
Ещё одна интересная особенность библиотеки argparse в Python. Предоставьте список принимаемых значений на стадии добавления новой опции:
Хотите принимать числовые значения? Используйте range() для определения диапазона принимаемых значений:
Тогда значение, указанное вами в командной строке, автоматически сравнивается со списком допустимых значений:
Если его там нет, вы получите сообщение об ошибке.
Установите необходимость аргумента
Хотите заставить пользователя вводить необязательный аргумент? Используйте ключевое слово required :
Установите значение required в True , и пользователь должен будет указывать значение для этого аргумента:
Помните, что требование значения для необязательного аргумента считается плохой практикой. Пользователь не ожидает, что нужно указывать значение для необязательного аргумента.