Python: модуль argparse — опции командной строки в примерах

Автор: | 05/08/2014
 

Pythonargparse — модуль Python, заменивший более старую версию похожего по функциональности модуля optparse.

Назначение модуля — обработка опций и аргументов командной строки, с которой вызывается скрипт.

Модуль может не быть установлен вместе с Python:

# pydoc argparse
no Python documentation found for 'argparse'

Поэтому его придётся установить вручную. Например, на CentOS:

# yum search argparse
...
python-argparse.noarch : Optparse inspired command line parser for Python
# yum -y install python-argparse

Для FreeBSD:

# cd /usr/ports/ && make search name="argparse"
Port:   py27-argparse-1.2.1
Path:   /usr/ports/devel/py-argparse
Info:   Optparse-inspired command-line parsing library
Maint:  lwhsu@FreeBSD.org
B-deps: gettext-0.18.3.1 libiconv-1.14_3 py27-setuptools27-2.0.1 python27-2.7.6_4 readline-6.3.3_1
R-deps: gettext-0.18.3.1 libiconv-1.14_3 py27-setuptools27-2.0.1 python27-2.7.6_4 readline-6.3.3_1
WWW:    http://code.google.com/p/argparse/
# cd /usr/ports/devel/py-argparse && make install clean

Либо — установить с помощью pip или вручную.

Файл модуля во FreeBSD расположен в /usr/local/lib/python2.7/argparse.py, в CentOS/usr/lib/python2.6/site-packages/argparse.py.

Для BASH есть аналогичный модуль getopts.

Для первого примера возьмём скрипт с таким содержимым:

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-1', '--one' , help='This will be option One')

parser.parse_args()

Результат его запуска:

$ ./args.py -h
usage: args.py [-h] [-1 ONE]
optional arguments:
-h, --help         show this help message and exit
-1 ONE, --one ONE  This will be option One

Заметьте, что опция -h (или --help) в нём не задаётся вручную, она обрабатывается модулем «автоматически» (хотя это можно переназначить).

Основные действия будут выполнятся классом ArgumentParser модуля argparse.

Список методов класса можно получить так:

>>> for i in dir(argparse.ArgumentParser):
...   if not i.startswith('_'):
...     print i
...
add_argument
add_argument_group
add_mutually_exclusive_group
add_subparsers
convert_arg_line_to_args
error
exit
format_help
format_usage
format_version
get_default
parse_args
parse_known_args
print_help
print_usage
print_version
register
set_defaults

Мы рассмотрим использование двух — add_argument и parse_args.

Python argparse — добавление опций с помощью add_argument

Ситаксис add_argument:

add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

name или flags — имя опции, например foo или -f, —foo
action — тип действия, которое будет выполнятся при вызове опции (см. ниже action='store');
nargs — количество аргументов к опции, которые могут (должны) быть использованы;
const — константа, может потребовать некоторым типам действий или аргументам;
default — действие по-умолчанию, если опция пропущена (не вызвана), прмиеняется ко всем опциям, которым не назначен отдельный ключ default;
type — тип данных, в котором должен быть сохранён объект (данные), переданные аргументом к опции, например — str или int;
choices — контейнер допустимых значений для аргумента;
required — указатель, является ли опция обязательной;
help — краткое описание опции, используется в --help;
metavar — имя аргумента для опции, которое будет выводится в --help;
dest — имя опции, которое будет передано методу parse_args().

Тут отдельно надо остановиться на ключе «action«.

Ключ action может принимать такие значения:

  • 'store' — просто сохраняет в переменной «имя_опции» значение, переданное опции (действие по-умолчанию);
  • 'store_const' — сохраняет значение, заданное ключём const;
  • 'store_true' или 'store_false' — сохраняет значение True или False;
  • 'count' — счётчик количества экземпляров опции.

Больше значений смотрите тут>>>.

Рассмотрим несколько примеров добавления обрабатываемых опций.

add_argument — name или flags

Опции, задаваемые со знаком «-» будут считаться опциональными, тогда как заданные просто в виде "имя" — обязательными.

Например:

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-1', '--one', help='This will be option One')
parser.add_argument('two', help='This will be option two')
parser.add_argument('three', help='This will be option three')

print parser.parse_args()

Обратите внимание — тут мы добавили функцию print(), для вывода «пространства имён» опций.

Вызовем скрипт с опцией --help:

$ ./args.py -h
usage: args.py [-h] [-1 ONE] two three

positional arguments:
  two                This will be option two
  three              This will be option three

optional arguments:
  -h, --help         show this help message and exit
  -1 ONE, --one ONE  This will be option One

Теперь — попробуем запустить скрипт с указанием всех опций:

$ ./args.py  -1 first one two
Namespace(one='first', three='two', two='one')

Т.к. для опции -1 не указано действие — будет выполнено действие по-умолчанию action='store'. Для позиционных опций не требуется указание аргументов, т.к. его значение само по себе будет явятся аргументом.

Например — вызов опции --one (или -1) без указания аргумента вызовет ошибку:

$ ./args.py one two -1
usage: args.py [-h] [-1 ONE] two three
args.py: error: argument -1/--one: expected one argument

При этом — к вызову обязательны все позиционные опции, иначе будет ошибка:

$ ./args.py one -1 first
usage: args.py [-h] [-1 ONE] two three
args.py: error: too few arguments

add_argument — action

Рассмотрим допустимые действия для опций.

‘store’ — сохраняет значение, переданное опции (действие по-умолчанию)

Т.е., опции обязательно передать аргумент, который будет сохранён как её значение.

Например:

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-1', '--one', help='This will be option One')

print parser.parse_args()

Будет аналогичен такому коду:

parser.add_argument('-1', '--one', action='store', help='This will be option One')

Результат выполнения:

$ ./args.py --one first_argument
Namespace(one='first_argument')
‘store_const’ — сохраняет значение, заданное ключём const;

Изменим наш код:

parser.add_argument(‘-1’, ‘—one’, action=’store_const’, const=’1′, help=’This will be option One’)

$ ./args.py --one
Namespace(one='1')

Удобно использовать для передачи различных флагов.

Например:

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-1', '--one', action='store_const', const='1', help='This will be option One')

print parser.parse_args()

if parser.parse_args().one == '1':
        print 'That's it!'
else:
        print 'Here is nothing :-('

Вызовем скрипт с опцией --one:

$ ./args.py --one
Namespace(one='1')
That's it!

И без неё:

$ ./args.py
Namespace(one=None)
Here is nothing 🙁
‘store_true’ или ‘store_false’ — сохраняет значение True или False

Похож по действию на store_const, с той разницей что хранит только True или False.

Изменим код:

parser.add_argument('-1', '--one', action='store_true', help='This will be option One')

Результат:

$ ./args.py -1
Namespace(one=True)

Тогда как вызов без опции --one задаст значение False:

$ ./args.py
Namespace(one=False)

И наоборот:

parser.add_argument('-1', '--one', action='store_false', help='This will be option One')
$ ./args.py -1
Namespace(one=False)

И без опции:

$ ./args.py
Namespace(one=True)

Соответственно — можем использовать код:

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-1', '--one', action='store_true', help='This will be option One')

print parser.parse_args()

res = parser.parse_args()

if res.one:
        print 'First is True!'
else:
        print 'First is nothing :-('

Обратите внимание, что тут мы создали объект res, который является экземпляром класса argparse с вызовом метода ArgumentParser — просто, что бы не писать лишний текст.

Результат выполнения:

$ ./args.py -1
Namespace(one=True)
First is True!

И без опции:

$ ./args.py
Namespace(one=False)
First is nothing 🙁
‘count’ — счётчик количества экземпляров опции

Изменим наш код:

parser.add_argument('-1', '--one', action='count', help='This will be option One')

И вызовем его с одним ключём:

$ ./args.py -1
Namespace(one=1)

Или двумя:

$ ./args.py -11
Namespace(one=2)

Пример использования — указать уровень «подробности» режима verbosity, когда можно указать -v, -vv или -vvv.

add_argument — nargs

Ключ nargs поддерживает такие значения:

  • N — количество аргументов к опции;
  • ? — если присутствует один аргумент — он будет сохранён, иначе — будет использовано значение из ключа default;
  • * — все переданные аргументы будут сохранены в один список;
  • + — то же, что и * — но если нет хотя бы одного аргумента — будет выдано сообщение об ошибке;
nargs с N-аргументов:

Пример кода:

parser.add_argument('-1', '--one', nargs=2, help='This will be option One')

Обратите внимание, что тут 2 указывается без кавычек — иначе интерпретатор будет рассматривать значение как string (строку), что вызовет ошибку.

Если вызвать без указания аргументов к опции -1 — будет выдано сообщение об ошибке:

$ ./args.py -1
usage: args.py [-h] [-1 ONE ONE]
args.py: error: argument -1/--one: expected 2 argument(s)

Вызываем с двумя аргументами — и получаем список:

$ ./args.py -1 one two
Namespace(one=['one', 'two'])
nargs с «?» аргументов:
parser.add_argument('-1', '--one', nargs='?', help='This will be option One')
$ ./args.py -1 first
Namespace(one='first')

Или передать имя файла:

$ ./args.py -1 file.txt
Namespace(one='file.txt')

При вызове без аргумента — значение переменной будет задано как None:

$ ./args.py -1
Namespace(one=None)

Изменить это можно с помощью ключей const и default.

Немного изменим наш код:

parser.add_argument('-1', '--one', nargs='?', const='const-one', default='default-one', help='This will be option One')
parser.add_argument('-2', '--two', nargs='?', const='const-two', default='default-two', help='This will be option Two')

И результаты:

$ ./args.py -1 -2
Namespace(one='const-one', two='const-two')
$ ./args.py -1 first -2
Namespace(one='first', two='const-two')
$ ./args.py -1 first -2 second
Namespace(one='first', two='second')
nargs с «*» аргументов:

Изменим пример:

parser.add_argument('-1', '--one', nargs='*', help='This will be option One')

При вызове без аргументов опции — создаст пустой список:

$ ./args.py -1 one two three
Namespace(one=['one', 'two', 'three'])

При вызове с любым количеством аргументов — добавит их все в один список:

$ ./args.py -1 one two three
Namespace(one=['one', 'two', 'three'])

Далее со списком можно выполнять любые стандартные операции:

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-1', '--one', nargs='*', help='This will be option One')

print parser.parse_args()

res = parser.parse_args()

for i in res.one:
        print i

И результат:

$ ./args.py -1 one two three
Namespace(one=['one', 'two', 'three'])
one
two
three
nargs с «+» аргументов:

Требуется наличие хотя бы одного аргумента к опции.

Напрмиер:

parser.add_argument('-1', '--one', nargs='+', help='This will be option One')

Вызов без аргумента:

$ ./args.py -1
usage: args.py [-h] [-1 ONE [ONE ...]]
args.py: error: argument -1/--one: expected at least one argument

С одним аргументом:

$ ./args.py -1 one
Namespace(one=['one'])

Несколькими:

$ ./args.py -1 one two three
Namespace(one=['one', 'two', 'three'])

add_argument — choices

Т.к. мы кратко рассмотрели const  и default  выше — то пропустим их, и перейдём к слудющему ключу — choices.

Изменим пример:

parser.add_argument('-1', '--one', choices=['1', '2', '3'], help='This will be option One')

В результате — аргумент к опции должен быть только из предложенного списка:

$ ./args.py -1 one two three
usage: args.py [-h] [-1 {1,2,3}]
args.py: error: argument -1/--one: invalid choice: 'one' (choose from 1, 2, 3)

Правильный выбор:

$ ./args.py -1 1
Namespace(one='1')
1

add_argument — required

Указание является ли опция обязательной:

parser.add_argument('-1', '--one', required=True, help='This will be option One')
$ ./args.py
usage: args.py [-h] -1 ONE
args.py: error: argument -1/--one is required
$ ./args.py -1 1
Namespace(one='1')
1

add_argument — dest

Замена имени переменной. По-умолчанию — имя переменной формируется из «длинного имени» опции (если есть, в нашем примере это --one), или из «короткого» (если нет «длинного», в нашем примере это -1):

parser.add_argument('-1', '--one', help='This will be option One')
$ ./args.py -1 one
Namespace(one='one')
parser.add_argument('-1', help='This will be option One')
$ ./args.py -1 one
Namespace(1='one')

Зададим другое имя:

parser.add_argument('-1', '--one', dest='firstvar', help='This will be option One')

Результат:

$ ./args.py -1 one
Namespace(firstvar='one')

Что бы проверить, что скрипт вызван хотя бы с одной опцией — можно использовать такой способ:

#!/usr/bin/env python

import argparse
import sys

parser = argparse.ArgumentParser()

parser.add_argument('-1', '--one', dest='firstvar', help='This will be option One')

if len(sys.argv) == 1:
        print 'nERROR! You must specify at least one option.n'
        parser.print_help()

И вызовем скрипт без опций:

$ ./args.py

ERROR! You must specify at least one option.

usage: args.py [-h] [-1 FIRSTVAR]

optional arguments:
  -h, --help            show this help message and exit
  -1 FIRSTVAR, --one FIRSTVAR
                        This will be option One

На этом, пожалуй, всё.

Ссылки по теме:

https://docs.python.org
https://docs.python.org
http://habrahabr.ru/post/144416/
http://sakalr.blogspot.com