Python

Если вы хотите разрабатывать ПО на Python, то умение использовать argparse в своих скриптах будет крайне полезным. Если же вы специалист по данным, то, возможно, вам нужно преобразовать код из Jupyter Notebook в воспроизводимый скрипт. Для многих начинающих разработчиков этот шаг кажется сложным и практически непреодолимым, но своей статьей я надеюсь сделать его менее пугающим.

argparse — рекомендуемый модуль стандартной библиотеки Python для обработки аргументов командной строки.

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

Jupyter великолепен

По ту сторону Jupyter Notebook

Когда я впервые увидел argparse, первой мыслью было: “Что это за чёрная магия?”. Казалось, что переключиться на Jupyter Notebook — гораздо более лёгкое решение. Как оказалось позже, это решение было полукомпромиссным.

Я хотел запускать всю программу целиком, а не каждую ячейку блокнота по отдельности. Скрипт с использованием argparse был бы гораздо более удобным в использовании и менее трудоёмким. К сожалению, я слишком торопился и не смог найти документацию, которая позволила бы разобраться с модулем.

С этого момента прошло достаточно много времени, я узнал больше об argparse. Он незаменим!

Вот то, что вам нужно знать.

Зачем использовать argparse?

Как вы уже поняли из названия, argparse парсит аргументы.

Использование этого модуля даёт пользователям программы возможность передавать аргументы во время выполнения программы. Это инструмент взаимодействия разработчиков и пользователей, которыми, к слову, можете оказаться и вы.😃

Использование argparse позволяет менять что-то в программе без изменения кода, а, значит, делает саму программу адаптивной.

Python тоже великолепен

Пример

Допустим, у вас есть директория с видео и вы хотите преобразовать эти видео в картинки, используя OpenCV. Используйте argparse для того, чтобы пользователь мог самостоятельно выбрать папку исходников и папку для сохранения. Вот как это будет выглядеть:

# videos.py
import argparse
parser = argparse.ArgumentParser(description='Videos to images')
parser.add_argument('indir', type=str, help='Input dir for videos')
parser.add_argument('outdir', type=str, help='Output dir for image')
args = parser.parse_args()
print(args.indir)

Для начала импортируем саму библиотеку. Затем создаём парсер с описанием и переменную indir при помощи метода parser.add_argument(). Типом переменной указываем str (строковый тип данных), добавляем вспомогательное сообщение — описание переменной. Ту же последовательность действий выполняем для outdir. Затем переменной args присваиваются значения считанных (parsed) аргументов.

Теперь можем выполнить эту команду из командной строки:

python videos.py /videos /images

Заметьте, что значения аргументов не нужно заключать в кавычки.

При корректной работе вывод в терминал должен быть таким: /videos

Мы только что увидели, что можем использовать переменную в нашей программе args.indir где угодно. Разве это не круто?

Теперь вы постигли магию argparse!

Как они это делают?

Что ещё нужно знать про argparse?

Метод parser.add_argument(‘indir’, type=str, help=’Input dir for videos’) создаёт позиционный параметр, то есть тот, для которого важен порядок расположения. Первый передаваемый аргумент становится первым параметром, второй — вторым.

Что произойдёт, если вы решите нарушить этот порядок и выполнить python videos.py?

Вы получите ошибку: videos.py: error: the following arguments are required: indir, outdir. Позиционные аргументы всегда должны передаваться так, как это было задумано в коде.

Опциональные параметры

Вернёмся к нашей программе для преобразования видео в картинки. Что произойдёт при попытке выполнить команду python videos.py — help?

Вы получите справочную информацию о вашем скрипте, чтобы вы знали, что делать.

Результат выполнения команды python videos.py — help

Отлично! help — пример опционального параметра. Заметьте, что это — единственный параметр, который получаете сразу, но вы можете собственноручно создать и другие.

Создаются они практически так же, как и позиционные, за исключением того, что в начале названия у них '--' (или '-’ и один дополнительный символ для укороченной версии). Например, создадим опциональный параметр так: 

parser.add_argument(‘-m’, ‘--my_optional’)

В следующем примере показано создание и обращение к опциональным параметрам. Заметьте, что в этом случае мы устанавливаем int как тип данных. Разрешается использовать любой другой тип данных, поддерживаемый Python.

# my_example.py
import argparse
parser = argparse.ArgumentParser(description='My example explanation')
parser.add_argument(
    '--my_optional',
    default=2,
    help='provide an integer (default: 2)'
)
my_namespace = parser.parse_args()
print(my_namespace.my_optional)

Заметьте, что аргумент, определённый как ‘--my_optional’, становится переменной пространства имён без знаков тире: ‘my_namespace.my_optional’.

Также заметьте, что для опциональных параметров можно задавать значения по умолчанию. В этом примере результатом выполнения команды python my_example.py будет 2.

Опциональные аргументы могут быть заданы непосредственно во время вызова программы через командную строку таким образом: python my_example.py — my_optional=3. В таком случае программа выведет 3.

Целые числа

Это далеко не все возможности argparse. Например, ещё можно соединять аргументы в списки при помощи nargs=’*’. Также можно задавать ограничения значения при помощи choices. Для того чтобы узнать больше об этом модуле, ознакомьтесь с документацией.

Где ещё использовать argparse?

Также можно использовать argparse при работе с программами в контейнере Docker. Если вы хотите отправить скрипту данные во время сборки, сделайте это при помощи RUN. Если же хотите передать входные данные в программу непосредственно во время её работы, используйте CMD или ENTRYPOINT. 

Заключение

Вы узнали об основах работы с argparse. Теперь вы знаете, как передавать позиционные и опциональные параметры вашей программе через командную строку, как устанавливать опциональные аргументы по умолчанию.

Документация argparse.

Надеюсь, статья оказалась интересной для вас. Спасибо за прочтение!

Перевод статьи Jeff Hale: Learn Enough Python to be Useful: argparse