argparse Python

Содержание
Введение
Пример
version
Необязательный аргумент
Значения по умолчанию
Похожие статьи

Введение

Это статья про библиотеку argparse для работы с агрументами, которые передаются в скрипт извне. Например, из терминала.

Передача аргументов в скрипт это распространённая практика для CI/CD.

Про обычные аргументы, то есть такие, которые передаются в функцию внутри модуля, читайте статью *args, **kwargs

Про применение sys.argv[] без обёрток читайте здесь

Здесь будут использованы приёмы, которые можно изучить в следующих статьях:

Exceptions , Менеджер контекста , Списки , Строки , Работа с файлами

Пример

import argparse parser = argparse.ArgumentParser() parser.add_argument("filename", help="file to read") args = parser.parse_args() print(args)

python argparse_demo.py site.txt

Namespace(filename='site.txt')

filename попал в Namespace, так как по умолчанию над всеми аргументами совершается действие (action="store")

Можно было явно указать это слеюущим образом:

import argparse parser = argparse.ArgumentParser() parser.add_argument("filename", action="store", help="file to read")

Если не передать ни одного аргумента

python argparse_demo.py

usage: argparse_demo.py [-h] filename argparse_demo.py: error: the following arguments are required: filename

Если передать лишний аргумент

python argparse_demo.py site.txt demo.txt

usage: argparse_demo.py [-h] filename argparse_demo.py: error: unrecognized arguments: demo.txt

Получить справку по аргументу можно с помощью опции -h

python argparse_demo.py -h filename

usage: argparse_demo.py [-h] filename positional arguments: filename file to read options: -h, --help show this help message and exit

version

У метода add_argument() есть несколько ключевых аргументов.

version это один из них.

Обычно это действие action="version" используется вместе с флагом --version

Скрипт, вызванный с флагом, у которого стоит action="version" не будет выполняться по стандартному сценарию.

Вместо этого будет выведено значение aргумента version, которые можно сформировать определённым образом.

Слово version здесь очень перегружено. Чтобы не запутаться ещё раз отметим:

--version - это флаг, который используется при вызове скрипта.

action="version" - указывает, что действие, которое выполняет этот флаг это уже не store а version

version="%(prog)s 2.0" - указывает на то как именно выводить версию.

# argparse_version.py import argparse parser = argparse.ArgumentParser(description="version action demo", prog="PROG") parser.add_argument("--version", "-v", action="version", version="%(prog)s 2.0") args = parser.parse_args() print(args)

Если не задать prog= будет использовано имя файла.

python argparse_version.py --version

PROG 2.0

Видим, что после вывода версии не был напечатан Namespace(), так как скрипт не отработал дефолтный сценарий.

В следующей главе разберём необязательные аргументы с дефолтным action="store"

РЕКЛАМА хостинга Beget, которым я пользуюсь более десяти лет

Изображение баннера

Конец рекламы хостинга Beget, который я всем рекомендую.

Необязательный аргумент

Чтобы показать, что аргумент является необязательным перед его именем добавляют два дефиса --.

Такой аргумент часто называют флагом. Обычно после длинной версии с двумя дефисами, через запятую добавляют короткую версию из одной буквы с одним дефисом -.

Это стандартная практика, которая не ограничивается скриптами на Python, а используется почти везде.

Типичный пример такого аргумента во многих скриптах это --version, -v

Добавим два необязательных аргумента: --limit и --version

# reverse_file.py import argparse parser = argparse.ArgumentParser(description='Reverse a file') parser.add_argument( "filename", action="store", help="the file to read") parser.add_argument( "--limit", "-l", action="store", type=int, help="the number of lines to read" ) parser.add_argument( "--version", "-v", action="version", version="%(prog)s 1.0" ) args = parser.parse_args() print(args)

Этот скрипт нельзя выполнить без обязательного аргумента filename

Помимо случая, когда вызов идёт с флагом --version

python reverse_file.py --version

reverse_file.py 1.0

Но можно спокойно выполнить скрипт не передав --limit

python reverse_file.py sites.txt

Namespace(filename='sites.txt', limit=None)

По умолчанию --limit получил None.

Про --version в Namespace нет упоминаний.

--version это не обычный аргумент, потому что имеет опцию action="version" а не action="store" как у .

Передать необязательный аргумент --limit можно следующим оригинальным образом:

python reverse_file.py sites.txt -l 10

Namespace(filename='sites.txt', limit=10)

Можно передать --limit строкой, если она конвертируема в int

python reverse_file.py sites.txt -l "5"

Namespace(filename='sites.txt', limit=5)

Если аргумент не конвертируем в int получим ошибку

python reverse_file.py sites.txt -l "a"

usage: reverse_file.py [-h] [--limit LIMIT] [--version] filename reverse_file.py: error: argument --limit/-l: invalid int value: 'a'

Добавим в скрипт функционал перезаписывающий файл задом-наперёд.

import argparse parser = argparse.ArgumentParser(description='Reverse a file') parser.add_argument("filename", help="file to read") parser.add_argument("--limit", "-l", type=int, help="number of lines to read" ) parser.add_argument( "--version", "-v", action="version", version="%(prog)s 1.0" ) args = parser.parse_args() with open(args.filename) as f: lines = f.readlines() lines.reverse() if args.limit: lines = lines[:args.limit] for line in lines: print(line.strip()[::-1])

Обратите внимание, на то, что переданные аргументы после парсинга доступны как атрибуты объекта args

Применим скрипт к файлу sites.txt

andreyolegovich.ru aredel.com devhops.ru heihei.ru testsetup.ru topbicycle.ru

python reverse_file.py sites.txt

ur.elcycibpot ur.putestset ur.iehieh ur.spohved moc.ledera ur.hcivogeloyerdna

Применим флаг --limit

python reverse_file.py sites.txt --limit 3

ur.elcycibpot ur.putestset ur.iehieh

Теперь, когда мы хотим прочитать настоящий файл, можно столкнуться с его отсутствием

python reverse_file.py none.txt

Traceback (most recent call last): File "C:\python\reverse_file_form.py", line 14, in <module> with open(args.filename) as f: ^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: 'none.txt'

Желательно заранее подготовиться к этому с помощью явной проверки существования файла или try

Про менеджер контекста (with) можете прочитать здесь

import argparse parser = argparse.ArgumentParser(description='Reverse a file') parser.add_argument("filename", help="file to read") parser.add_argument("--limit", "-l", type=int, help="number of lines to read" ) parser.add_argument( "--version", "-v", action="version", version="%(prog)s 1.0" ) args = parser.parse_args() try: f = open(args.filename) except FileNotFoundError as e: print(e) else: with f: lines = f.readlines() lines.reverse() if args.limit: lines = lines[:args.limit] for line in lines: print(line.strip()[::-1])

python reverse_file.py none.txt

[Errno 2] No such file or directory: 'none.txt'

Exit Statuses

В предыдущей главе мы обрабатывали ошибку с отсутствующим файлом с помощью try

python reverse_file.py none.txt

[Errno 2] No such file or directory: 'none.txt'

Файл не найден, но скрипт выполнился корректно. Если мы сейчас проверим статус он будет успешным.

Например, в PowerShell :

echo $?

True

В Bash

echo $?

0

Нас может не устраивать такой результат. Например, нужно чтобы CI скрипт вызвавший наш модуль получил явный статус об ошибке и сделал соответствующие действия.

Для решения этой задачи используют sys.exit

import argparse import sys parser = argparse.ArgumentParser(description='Reverse a file') parser.add_argument("filename", help="file to read") parser.add_argument("--limit", "-l", type=int, help="number of lines to read" ) parser.add_argument( "--version", "-v", action="version", version="%(prog)s 1.0" ) args = parser.parse_args() try: f = open(args.filename) except FileNotFoundError as e: print(e) sys.exit(2) else: with f: lines = f.readlines() lines.reverse() if args.limit: lines = lines[:args.limit] for line in lines: print(line.strip()[::-1])

python reverse_file.py none.txt

[Errno 2] No such file or directory: 'none.txt'

echo $?

False

echo $?

2

Значения по умолчанию

Чтобы задать значения по умолчанию используется аргумент default.

Пример скрипта, который получает IP адрес и порт для выполнения запроса, но также имеет дефолтные значения.

import requests import argparse parser = argparse.ArgumentParser() parser.add_argument("--ip", nargs="?", default="10.8.1.101", type=str) parser.add_argument("--port", nargs="?", default="5000", type=str) args = parser.parse_args() r = requests.get(f"http://{args.ip}:{args.port}/health") print(r.status_code)

Автор статьи: Андрей Олегович

Похожие статьи
Command Line Interface
sys.argv[]

РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе

Конец рекламы. Если там пусто считайте это рекламой моей телеги

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: