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

Автор: | 08/05/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:  [email protected]
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