argparse — Парсер командной строки для опций, аргументов и подкоманд
Новая версия с 3.2.
Исходный код: Lib/argparse.py
Модуль argparse упрощает создание удобных пользовательских интерфейсов командной строки. Программа определяет требуемые аргументы, а argparse выяснет, как извлечь эти аргументы из sys.argv. Модуль argparse также автоматически генерирует сообщения справки и использования и выводит ошибки, когда пользователи предоставляют программе недопустимые аргументы.
1. Пример
Следующий код представляет собой программу Python, которая принимает список целых чисел и выводит либо сумму, либо максимальное значение:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
print(args.accumulate(args.integers))
Предполагая, что код Python выше сохранён в файле prog.py, его можно запустить в командной строке и получить полезные сообщения справки:
$ python prog.py -h usage: prog.py [-h] [--sum] N [N ...] Process some integers. positional arguments: N an integer for the accumulator optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max)
При запуске с соответствующими аргументами, он выводит сумму или максимальное значение целых чисел из командной строки:
$ python prog.py 1 2 3 4 4 $ python prog.py 1 2 3 4 --sum 10
Если переданы неверные аргументы, будет выдана ошибка:
$ python prog.py a b c usage: prog.py [-h] [--sum] N [N ...] prog.py: error: argument N: invalid int value: 'a'
В следующих разделах мы разберём этот пример.
1.1. Создание парсера
Первый шаг при использовании argparse заключается в создании объекта ArgumentParser:
>>> parser = argparse.ArgumentParser(description='Process some integers.')
Объект ArgumentParser будет содержать всю необходимую информацию для парсинга командной строки в типы данных Python.
1.2. Добавление аргументов
Заполнение объекта ArgumentParser информацией об аргументах программы выполняется путём вызова метода add_argument(). Обычно эти вызовы сообщают объекту ArgumentParser, как преобразовать строки из командной строки в объекты. Эта информация хранится и используется при вызове parse_args(). Например:
>>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
... help='an integer for the accumulator')
>>> parser.add_argument('--sum', dest='accumulate', action='store_const',
... const=sum, default=max,
... help='sum the integers (default: find the max)')
Позже, вызов parse_args() вернёт объект с двумя атрибутами, integers и accumulate. Атрибут integers будет списком из одного или нескольких целых чисел, а атрибут accumulate будет либо функцией sum(), если --sum был указан в командной строке, либо функцией max(), если он не был указан.
1.3. Парсинг аргументов
Объект ArgumentParser парсит аргументы через метод parse_args(). Это позволит проанализировать командную строку, преобразовать каждый аргумент в соответствующий тип и затем выполнить соответствующее действие. В большинстве случаев это означает создание простого объекта Namespace из атрибутов, полученных из командной строки:
>>> parser.parse_args(['--sum', '7', '-1', '42']) Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])
В скрипте, parse_args() обычно вызывается без аргументов, и ArgumentParser автоматически определит аргументы командной строки из sys.argv.
2. Объекты ArgumentParser
-
class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True) -
Создаёт новый объект
ArgumentParser. Все параметры должны передаваться в качестве ключевых аргументов. Каждый параметр имеет собственное более подробное описание ниже, но вкратце они:-
prog - Имя программы (по умолчанию:
sys.argv[0]) - usage - Строка, описывающая использование программы (по умолчанию: генерируется из аргументов, добавленных в парсер)
- description - Текст, отображаемый перед справкой по аргументам (по умолчанию: нет)
- epilog - Текст, отображаемый после справки по аргументам (по умолчанию: нет)
-
parents - Список объектов
ArgumentParser, аргументы которых также должны быть включены - formatter_class - Класс для настройки вывода справки
- prefix_chars - Набор символов, являющихся префиксом необязательных аргументов (по умолчанию: ‘-‘)
-
fromfile_prefix_chars - Набор символов, являющихся префиксом файлов, из которых должны считываться дополнительные аргументы (по умолчанию:
None) -
argument_default - Глобальное значение по умолчанию для аргументов (по умолчанию:
None) - conflict_handler - Стратегия разрешения конфликтов между опциональными аргументами (обычно не требуется)
-
add_help - Добавление опции справки к парсеру (по умолчанию:
-h/--help) -
allow_abbrev - Разрешает сокращение длинных опций, если сокращение однозначно. (по умолчанию:
True)
Изменено в версии 3.5: Добавлен параметр allow_abbrev.
-
prog - Имя программы (по умолчанию:
В следующих разделах описывается использование каждого из этих параметров.
2.1. prog
По умолчанию, объекты ArgumentParser используют sys.argv[0] для определения способа отображения имени программы в сообщениях справки. Это значение по умолчанию почти всегда желательно, так как оно позволит сообщениям справки соответствовать тому, как программа была вызвана в командной строке. Например, рассмотрим файл с именем myprogram.py со следующим кодом:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()
Справка для этой программы отобразит myprogram.py в качестве имени программы (независимо от того, откуда программа была вызвана):
$ python myprogram.py --help usage: myprogram.py [-h] [--foo FOO] optional arguments: -h, --help show this help message and exit --foo FOO foo help $ cd .. $ python subdir/myprogram.py --help usage: myprogram.py [-h] [--foo FOO] optional arguments: -h, --help show this help message and exit --foo FOO foo help
Чтобы изменить это поведение по умолчанию, можно указать другое значение, используя аргумент prog= для ArgumentParser:
>>> parser = argparse.ArgumentParser(prog='myprogram') >>> parser.print_help() usage: myprogram [-h] optional arguments: -h, --help show this help message and exit
Обратите внимание, что имя программы, независимо от того, определено ли оно из sys.argv[0] или из аргумента prog=, доступно для сообщений справки с помощью спецификатора формата %(prog)s.
>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.add_argument('--foo', help='foo of the %(prog)s program')
>>> parser.print_help()
usage: myprogram [-h] [--foo FOO]
optional arguments:
-h, --help show this help message and exit
--foo FOO foo of the myprogram program
2.2. usage
По умолчанию, ArgumentParser вычисляет сообщение об использовании из содержащихся в нём аргументов:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', nargs='?', help='foo help')
>>> parser.add_argument('bar', nargs='+', help='bar help')
>>> parser.print_help()
usage: PROG [-h] [--foo [FOO]] bar [bar ...]
positional arguments:
bar bar help
optional arguments:
-h, --help show this help message and exit
--foo [FOO] foo help
Сообщения по умолчанию можно переопределить с помощью ключевого аргумента usage=:
>>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
>>> parser.add_argument('--foo', nargs='?', help='foo help')
>>> parser.add_argument('bar', nargs='+', help='bar help')
>>> parser.print_help()
usage: PROG [options]
positional arguments:
bar bar help
optional arguments:
-h, --help show this help message and exit
--foo [FOO] foo help
Специальный формат %(prog)s доступен для заполнения имени программы в сообщениях об использовании.
2.3. description
Большинство вызовов конструктора ArgumentParser будут использовать ключевой аргумент description=. Этот аргумент даёт краткое описание того, что делает программа и как она работает. В сообщениях справки описание отображается между строкой использования командной строки и сообщениями справки по различным аргументам:
>>> parser = argparse.ArgumentParser(description='A foo that bars') >>> parser.print_help() usage: argparse.py [-h] A foo that bars optional arguments: -h, --help show this help message and exit
По умолчанию описание будет переноситься на следующую строку, чтобы уместиться в заданном пространстве. Чтобы изменить это поведение, см. аргумент formatter_class.
2.4. epilog
Некоторые программы хотели бы отображать дополнительное описание программы после описания аргументов. Такой текст может быть задан с помощью аргумента epilog= для ArgumentParser:
>>> parser = argparse.ArgumentParser( ... description='A foo that bars', ... epilog="And that's how you'd foo a bar") >>> parser.print_help() usage: argparse.py [-h] A foo that bars optional arguments: -h, --help show this help message and exit And that's how you'd foo a bar
Как и с аргументом description, текст epilog= по умолчанию переносится на следующую строку, но это поведение можно настроить с помощью аргумента formatter_class для ArgumentParser.
2.5. parents
Иногда несколько парсеров используют общий набор аргументов. Вместо повторения определений этих аргументов можно использовать единственный парсер со всеми общими аргументами и передать его в аргумент parents= к ArgumentParser. Аргумент parents= принимает список объектов ArgumentParser, собирает все позиционные и необязательные действия из них и добавляет эти действия к объекту ArgumentParser, который строится:
>>> parent_parser = argparse.ArgumentParser(add_help=False)
>>> parent_parser.add_argument('--parent', type=int)
>>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> foo_parser.add_argument('foo')
>>> foo_parser.parse_args(['--parent', '2', 'XXX'])
Namespace(foo='XXX', parent=2)
>>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> bar_parser.add_argument('--bar')
>>> bar_parser.parse_args(['--bar', 'YYY'])
Namespace(bar='YYY', parent=None)
Обратите внимание, что большинство парсеров-родителей будут указывать add_help=False. В противном случае, ArgumentParser увидит две -h/--help опции (одну в родительском и одну в дочернем) и выдаст ошибку.
Примечание
Необходимо полностью инициализировать парсеры перед передачей их через parents=. Если вы измените родительские парсеры после дочернего парсера, эти изменения не будут отражены в дочернем.
2.6. форматтер_класса
ArgumentParser объекты позволяют настроить форматирование справки, указав альтернативный класс форматирования. В настоящее время существуют четыре таких класса:
-
class argparse.RawDescriptionHelpFormatter -
class argparse.RawTextHelpFormatter -
class argparse.ArgumentDefaultsHelpFormatter -
class argparse.MetavarTypeHelpFormatter
RawDescriptionHelpFormatter и RawTextHelpFormatter обеспечивают больший контроль над отображением текстовых описаний. По умолчанию, объекты ArgumentParser выполняют перенос строк для текстов описания и эпилога в сообщениях справки командной строки:
>>> parser = argparse.ArgumentParser( ... prog='PROG', ... description='''this description ... was indented weird ... but that is okay''', ... epilog=''' ... likewise for this epilog whose whitespace will ... be cleaned up and whose words will be wrapped ... across a couple lines''') >>> parser.print_help() usage: PROG [-h] this description was indented weird but that is okay optional arguments: -h, --help show this help message and exit likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines
Передача RawDescriptionHelpFormatter в качестве formatter_class= указывает на то, что описание и эпилог уже отформатированы и не должны быть разбиты на строки:
>>> parser = argparse.ArgumentParser(
... prog='PROG',
... formatter_class=argparse.RawDescriptionHelpFormatter,
... description=textwrap.dedent('''\
... Please do not mess up this text!
... --------------------------------
... I have indented it
... exactly the way
... I want it
... '''))
>>> parser.print_help()
usage: PROG [-h]
Please do not mess up this text!
--------------------------------
I have indented it
exactly the way
I want it
optional arguments:
-h, --help show this help message and exit
RawTextHelpFormatter сохраняет отступы для всех типов текстовой справки, включая описания аргументов.
ArgumentDefaultsHelpFormatter автоматически добавляет информацию о значениях по умолчанию в каждое из сообщений справки по аргументу:
>>> parser = argparse.ArgumentParser(
... prog='PROG',
... formatter_class=argparse.ArgumentDefaultsHelpFormatter)
>>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
>>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
>>> parser.print_help()
usage: PROG [-h] [--foo FOO] [bar [bar ...]]
positional arguments:
bar BAR! (default: [1, 2, 3])
optional arguments:
-h, --help show this help message and exit
--foo FOO FOO! (default: 42)
MetavarTypeHelpFormatter использует имя аргумента тип для каждого аргумента в качестве отображаемого имени его значений (вместо использования dest, как это делает обычный форматировщик):
>>> parser = argparse.ArgumentParser(
... prog='PROG',
... formatter_class=argparse.MetavarTypeHelpFormatter)
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', type=float)
>>> parser.print_help()
usage: PROG [-h] [--foo int] float
positional arguments:
float
optional arguments:
-h, --help show this help message and exit
--foo int
2.7. prefix_chars
Большинство опций командной строки будут использовать - в качестве префикса, например -f/--foo. Парсеры, которым требуется поддержка различных или дополнительных символов префикса, например для опций, таких как +f или /foo, могут указать их с помощью аргумента prefix_chars= конструктору ArgumentParser:
>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
>>> parser.add_argument('+f')
>>> parser.add_argument('++bar')
>>> parser.parse_args('+f X ++bar Y'.split())
Namespace(bar='Y', f='X')
Аргумент prefix_chars= по умолчанию равен '-'. Предоставление набора символов, не включающего -, приведет к запрету опций -f/--foo.
2.8. fromfile_prefix_chars
Иногда, например, при работе с длинными списками аргументов, может быть полезно хранить список аргументов в файле вместо ввода его в командной строке. Если аргумент fromfile_prefix_chars= задан конструктору ArgumentParser, то аргументы, начинающиеся с любого указанного символа, будут обрабатываться как файлы и будут заменены аргументами, которые они содержат. Например:
>>> with open('args.txt', 'w') as fp:
... fp.write('-f\nbar')
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
>>> parser.add_argument('-f')
>>> parser.parse_args(['-f', 'foo', '@args.txt'])
Namespace(f='bar')
Аргументы, считываемые из файла, по умолчанию должны быть по одному на строке (но см. также convert_arg_line_to_args()) и обрабатываются так, как если бы они находились в том же месте, что и аргумент исходной ссылки на файл в командной строке. Итак, в примере выше, выражение ['-f', 'foo', '@args.txt'] считается эквивалентным выражению ['-f', 'foo', '-f', 'bar'].
Аргумент fromfile_prefix_chars= по умолчанию равен None, что означает, что аргументы никогда не будут обрабатываться как ссылки на файлы.
2.9. argument_default
В целом, значения аргументов по умолчанию указываются либо путем передачи значения по умолчанию в add_argument(), либо путем вызова метода set_defaults() с определенным набором пар имя-значение. Иногда, однако, может быть полезно указать глобальное значение по умолчанию для аргументов. Это можно сделать, передав ключевое слово argument_default= в ArgumentParser. Например, чтобы глобально подавить создание атрибутов при вызовах parse_args(), мы передаем argument_default=SUPPRESS:
>>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar', nargs='?')
>>> parser.parse_args(['--foo', '1', 'BAR'])
Namespace(bar='BAR', foo='1')
>>> parser.parse_args([])
Namespace()
2.10. allow_abbrev
Обычно, когда вы передаете список аргументов методу parse_args() объекта ArgumentParser, он распознает сокращения длинных опций.
Эту функцию можно отключить, установив allow_abbrev в False:
>>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
>>> parser.add_argument('--foobar', action='store_true')
>>> parser.add_argument('--foonley', action='store_false')
>>> parser.parse_args(['--foon'])
usage: PROG [-h] [--foobar] [--foonley]
PROG: error: unrecognized arguments: --foon
Введено в версии 3.5.
2.11. conflict_handler
ArgumentParser объекты не допускают двух действий с одинаковой строкой опции. По умолчанию, объекты ArgumentParser генерируют исключение, если попытка создать аргумент со строкой опции, которая уже используется:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
Traceback (most recent call last):
..
ArgumentError: argument --foo: conflicting option string(s): --foo
Иногда (например, при использовании родителей) может быть полезно просто перезаписывать более старые аргументы с той же строкой опции. Для получения этого поведения значение 'resolve' может быть передано аргументу conflict_handler= ArgumentParser:
>>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
>>> parser.print_help()
usage: PROG [-h] [-f FOO] [--foo FOO]
optional arguments:
-h, --help show this help message and exit
-f FOO old foo help
--foo FOO new foo help
Обратите внимание, что объекты ArgumentParser удаляют действие только в том случае, если все его строки опций перезаписываются. Таким образом, в примере выше, старое действие -f/--foo сохраняется как действие -f, потому что только строка опции --foo была перезаписана.
2.12. add_help
По умолчанию, объекты ArgumentParser добавляют опцию, которая просто отображает сообщение справки парсера. Например, рассмотрим файл с именем myprogram.py, содержащий следующий код:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()
Если -h или --help заданы в командной строке, будет напечатана справка ArgumentParser:
$ python myprogram.py --help usage: myprogram.py [-h] [--foo FOO] optional arguments: -h, --help show this help message and exit --foo FOO foo help
Иногда может быть полезно отключить добавление этой опции справки. Этого можно добиться, передав False в качестве аргумента add_help= к ArgumentParser:
>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> parser.add_argument('--foo', help='foo help')
>>> parser.print_help()
usage: PROG [--foo FOO]
optional arguments:
--foo FOO foo help
Опция справки обычно -h/--help. Исключением из этого является тот случай, если prefix_chars= указан и не включает -, в этом случае -h и --help не являются допустимыми опциями. В этом случае первый символ в prefix_chars используется для префикса опций справки:
>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/') >>> parser.print_help() usage: PROG [+h] optional arguments: +h, ++help show this help message and exit
3. Метод add_argument()
-
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest]) -
Определите, как следует анализировать один командный аргумент. Каждый параметр имеет собственное более подробное описание ниже, но коротко они:
-
имя или флаги - либо имя, либо список строк-флагов, например
fooили-f, --foo. - действие - базовый тип действия, которое должно быть выполнено при обнаружении этого аргумента в командной строке.
- nargs - количество аргументов командной строки, которые следует потреблять.
- const - константное значение, требуемое некоторыми выбором действия и nargs.
- значение по умолчанию - значение, получаемое, если аргумент отсутствует в командной строке.
- тип - тип, в который следует преобразовать аргумент командной строки.
- choices - контейнер допустимых значений для аргумента.
- обязательность - требуется ли аргумент командной строки (только для необязательных).
- помощь - краткое описание действия аргумента.
- metavar - имя аргумента в сообщениях об использовании.
-
dest - имя атрибута, которое будет добавлено в объект, возвращаемый
parse_args().
-
имя или флаги - либо имя, либо список строк-флагов, например
В следующих разделах описывается использование каждого из этих параметров.
3.1. имя или флаги
Метод add_argument() должен знать, ожидается ли необязательный аргумент, например -f или --foo, или позиционный аргумент, например, список имен файлов. Поэтому первые аргументы, переданные в add_argument(), должны быть либо серией флагов, либо простым именем аргумента. Например, необязательный аргумент можно создать так:
>>> parser.add_argument('-f', '--foo')
в то время как позиционный аргумент можно создать так:
>>> parser.add_argument('bar')
Когда вызывается parse_args(), необязательные аргументы будут определяться префиксом -, а оставшиеся аргументы будут считаться позиционными:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args(['BAR'])
Namespace(bar='BAR', foo=None)
>>> parser.parse_args(['BAR', '--foo', 'FOO'])
Namespace(bar='BAR', foo='FOO')
>>> parser.parse_args(['--foo', 'FOO'])
usage: PROG [-h] [-f FOO] bar
PROG: error: too few arguments
3.2. действие
Объекты ArgumentParser связывают аргументы командной строки с действиями. Эти действия могут делать практически все с аргументами командной строки, связанными с ними, хотя большинство действий просто добавляют атрибут в объект, возвращаемый parse_args(). Аргумент action задает, как следует обрабатывать аргументы командной строки. Доступные действия:
-
'store'- просто сохраняет значение аргумента. Это действие по умолчанию. Например:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> parser.parse_args('--foo 1'.split()) Namespace(foo='1') -
'store_const'- сохраняет значение, указанное аргументом const. Действие'store_const'чаще всего используется с необязательными аргументами, которые указывают какой-либо флаг. Например:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_const', const=42) >>> parser.parse_args(['--foo']) Namespace(foo=42) -
'store_true'и'store_false'- это специальные случаи'store_const', используемые для сохранения значенийTrueиFalseсоответственно. Кроме того, они создают значения по умолчаниюFalseиTrueсоответственно. Например:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_true') >>> parser.add_argument('--bar', action='store_false') >>> parser.add_argument('--baz', action='store_false') >>> parser.parse_args('--foo --bar'.split()) Namespace(foo=True, bar=False, baz=True) -
'append'- сохраняет список и добавляет каждое значение аргумента в список. Это полезно, чтобы позволить одному и тому же варианту быть указанным несколько раз. Пример использования:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='append') >>> parser.parse_args('--foo 1 --foo 2'.split()) Namespace(foo=['1', '2']) -
'append_const'- сохраняет список и добавляет значение, указанное аргументом const, в список. (Обратите внимание, что аргумент const по умолчанию равенNone. Действие'append_const'обычно полезно, когда несколько аргументов должны хранить константы в одном и том же списке. Например:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--str', dest='types', action='append_const', const=str) >>> parser.add_argument('--int', dest='types', action='append_const', const=int) >>> parser.parse_args('--str --int'.split()) Namespace(types=[<class 'str'>, <class 'int'>]) -
'count'- подсчитывает количество раз, когда появляется ключевой аргумент. Например, это полезно для повышения уровней подробности:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--verbose', '-v', action='count') >>> parser.parse_args(['-vvv']) Namespace(verbose=3) -
'help'- выводит полное сообщение справки по всем параметрам в текущем анализаторе и затем завершает работу. По умолчанию действие справки автоматически добавляется в анализатор. Подробности о создании вывода см. в разделеArgumentParser. -
'version'- ожидает аргументversion=в вызовеadd_argument()и выводит информацию о версии и завершает работу при вызове:>>> import argparse >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--version', action='version', version='%(prog)s 2.0') >>> parser.parse_args(['--version']) PROG 2.0
Вы также можете указать произвольное действие, передав подкласс Action или другой объект, который реализует тот же интерфейс. Рекомендуемый способ сделать это - расширить Action, переопределив метод __call__ и, по желанию, метод __init__.
Пример пользовательского действия:
>>> class FooAction(argparse.Action):
... def __init__(self, option_strings, dest, nargs=None, **kwargs):
... if nargs is not None:
... raise ValueError("nargs not allowed")
... super(FooAction, self).__init__(option_strings, dest, **kwargs)
... def __call__(self, parser, namespace, values, option_string=None):
... print('%r %r %r' % (namespace, values, option_string))
... setattr(namespace, self.dest, values)
...
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action=FooAction)
>>> parser.add_argument('bar', action=FooAction)
>>> args = parser.parse_args('1 --foo 2'.split())
Namespace(bar=None, foo=None) '1' None
Namespace(bar='1', foo=None) '2' '--foo'
>>> args
Namespace(bar='1', foo='2')
Для получения более подробной информации см. Action.
3.3. nargs
Объекты ArgumentParser обычно связывают один аргумент командной строки с одним выполняемым действием. Аргумент nargs связывает различное количество аргументов командной строки с одним действием. Доступные значения:
-
N(целое число).Nаргументов из командной строки будут объединены в список. Например:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs=2) >>> parser.add_argument('bar', nargs=1) >>> parser.parse_args('c --foo a b'.split()) Namespace(bar=['c'], foo=['a', 'b'])Обратите внимание, что
nargs=1создаёт список из одного элемента. Это отличается от значения по умолчанию, при котором элемент генерируется сам по себе. -
'?'. Будет потреблен один аргумент из командной строки, если это возможно, и он будет представлен как один элемент. Если аргумент командной строки отсутствует, будет использовано значение из default. Обратите внимание, что для необязательных аргументов существует дополнительный случай — строка-опция присутствует, но за ней не следует аргумент командной строки. В этом случае будет использовано значение из const. Некоторые примеры для иллюстрации этого:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='?', const='c', default='d') >>> parser.add_argument('bar', nargs='?', default='d') >>> parser.parse_args(['XX', '--foo', 'YY']) Namespace(bar='XX', foo='YY') >>> parser.parse_args(['XX', '--foo']) Namespace(bar='XX', foo='c') >>> parser.parse_args([]) Namespace(bar='d', foo='d')Одним из наиболее распространенных применений
nargs='?'является возможность ввода и вывода файлов:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), ... default=sys.stdin) >>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), ... default=sys.stdout) >>> parser.parse_args(['input.txt', 'output.txt']) Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>) >>> parser.parse_args([]) Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>) -
'*'. Все присутствующие аргументы командной строки собираются в список. Обратите внимание, что обычно не имеет смысла иметь более одного позиционного аргумента сnargs='*', но несколько необязательных аргументов сnargs='*'возможны. Например:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='*') >>> parser.add_argument('--bar', nargs='*') >>> parser.add_argument('baz', nargs='*') >>> parser.parse_args('a b --foo x y --bar 1 2'.split()) Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y']) -
'+'. Как и'*', все присутствующие аргументы командной строки собираются в список. Кроме того, будет сгенерировано сообщение об ошибке, если не было хотя бы одного аргумента командной строки. Например:>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('foo', nargs='+') >>> parser.parse_args(['a', 'b']) Namespace(foo=['a', 'b']) >>> parser.parse_args([]) usage: PROG [-h] foo [foo ...] PROG: error: too few arguments -
argparse.REMAINDER. Все оставшиеся аргументы командной строки собираются в список. Это обычно полезно для командных утилит, которые вызывают другие командные утилиты:>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo') >>> parser.add_argument('command') >>> parser.add_argument('args', nargs=argparse.REMAINDER) >>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split())) Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
Если аргумент nargs не указан, количество потребляемых аргументов определяется действием action. Как правило, это означает, что будет потреблен один аргумент командной строки и будет произведен один элемент (а не список).
3.4. const
Аргумент const метода add_argument() используется для хранения постоянных значений, которые не считываются из командной строки, но требуются для различных действий ArgumentParser. Два наиболее распространенных использования:
- Когда
add_argument()вызывается сaction='store_const'илиaction='append_const'. Эти действия добавляют значениеconstк одному из атрибутов объекта, возвращаемогоparse_args(). См. описание действия action для примеров. - Когда
add_argument()вызывается со строками-опциями (например,-fили--foo) иnargs='?'. Это создаёт необязательный аргумент, за которым может следовать ноль или один аргумент командной строки. При анализе командной строки, если встречается строка-опция без последующего аргумента командной строки, вместо этого будет принято значениеconst. См. описание nargs для примеров.
С действиями 'store_const' и 'append_const' аргумент const должен быть указан. Для других действий он по умолчанию равен None.
3.5. значение по умолчанию
Все необязательные аргументы и некоторые позиционные аргументы могут быть опущены в командной строке. Аргумент default метода add_argument(), значение которого по умолчанию None, указывает, какое значение должно быть использовано, если аргумент командной строки отсутствует. Для необязательных аргументов используется значение default, если строка-опция не была указана в командной строке:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)
Если значение default является строкой, парсер анализирует значение так, как будто это аргумент командной строки. В частности, парсер применяет любой аргумент преобразования типа типа, если он предоставлен, прежде чем установить атрибут в возвращаемом значении Namespace. В противном случае парсер использует значение как есть:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--length', default='10', type=int)
>>> parser.add_argument('--width', default=10.5, type=int)
>>> parser.parse_args()
Namespace(length=10, width=10.5)
Для позиционных аргументов с nargs равным ? или *, значение default используется, когда аргумент командной строки отсутствует:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)
Предоставление default=argparse.SUPPRESS не приводит к добавлению атрибута, если аргумент командной строки отсутствует:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')
3.6. Тип
По умолчанию объекты ArgumentParser считывают аргументы командной строки как простые строки. Однако часто строка командной строки должна быть интерпретирована как другой тип, например, float или int. Аргумент type метода add_argument() позволяет выполнить все необходимые проверки типа и преобразования типов. Общие встроенные типы и функции могут быть использованы непосредственно в качестве значения аргумента type:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.add_argument('bar', type=open)
>>> parser.parse_args('2 temp.txt'.split())
Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)
См. раздел аргумента default для информации о том, когда аргумент type применяется к аргументам по умолчанию.
Для упрощения использования различных типов файлов модуль argparse предоставляет фабрику FileType, которая принимает аргументы mode=, bufsize=, encoding= и errors= функции open(). Например, FileType('w') можно использовать для создания записываемого файла:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar', type=argparse.FileType('w'))
>>> parser.parse_args(['out.txt'])
Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)
type= может принимать любой вызываемый объект, который принимает один строковый аргумент и возвращает преобразованное значение:
>>> def perfect_square(string):
... value = int(string)
... sqrt = math.sqrt(value)
... if sqrt != int(sqrt):
... msg = "%r is not a perfect square" % string
... raise argparse.ArgumentTypeError(msg)
... return value
...
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', type=perfect_square)
>>> parser.parse_args(['9'])
Namespace(foo=9)
>>> parser.parse_args(['7'])
usage: PROG [-h] foo
PROG: error: argument foo: '7' is not a perfect square
Аргумент choices может быть более удобен для анализаторов типов, которые просто проверяют диапазон значений:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', type=int, choices=range(5, 10))
>>> parser.parse_args(['7'])
Namespace(foo=7)
>>> parser.parse_args(['11'])
usage: PROG [-h] {5,6,7,8,9}
PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
См. раздел choices для получения более подробной информации.
3.7. Выбор
Некоторые аргументы командной строки должны быть выбраны из ограниченного набора значений. Это можно сделать, передав контейнерный объект в качестве аргумента choices методу add_argument(). При разборе командной строки значения аргументов будут проверены, и будет выведено сообщение об ошибке, если аргумент не был одним из допустимых значений:
>>> parser = argparse.ArgumentParser(prog='game.py')
>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
>>> parser.parse_args(['rock'])
Namespace(move='rock')
>>> parser.parse_args(['fire'])
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
'paper', 'scissors')
Обратите внимание, что проверка на включение в контейнер choices выполняется после выполнения любых преобразований типа типа, поэтому тип объектов в контейнере choices должен соответствовать типу, указанному в типе:
>>> parser = argparse.ArgumentParser(prog='doors.py')
>>> parser.add_argument('door', type=int, choices=range(1, 4))
>>> print(parser.parse_args(['3']))
Namespace(door=3)
>>> parser.parse_args(['4'])
usage: doors.py [-h] {1,2,3}
doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3)
Любой объект, поддерживающий оператор in, может быть передан как значение choices, поэтому объекты dict, объекты set, пользовательские контейнеры и т. д. поддерживаются.
3.8. Обязательность
В общем случае, модуль argparse предполагает, что флаги, такие как -f и --bar указывают на необязательные аргументы, которые всегда можно опустить в командной строке. Чтобы сделать опцию обязательной, можно указать True для аргумента required= метода add_argument():
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: argparse.py [-h] [--foo FOO]
argparse.py: error: option --foo is required
Как показывает пример, если опция отмечена как required, parse_args() сообщит об ошибке, если эта опция отсутствует в командной строке.
Примечание
Обязательные опции обычно считаются плохой практикой, потому что пользователи ожидают, что опции будут необязательными, и поэтому их следует избегать, когда это возможно.
3.9. Справка
Значение help — это строка, содержащая краткое описание аргумента. Когда пользователь запрашивает справку (обычно, используя -h или --help в командной строке), эти описания help будут отображаться с каждым аргументом:
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', action='store_true',
... help='foo the bars before frobbling')
>>> parser.add_argument('bar', nargs='+',
... help='one of the bars to be frobbled')
>>> parser.parse_args(['-h'])
usage: frobble [-h] [--foo] bar [bar ...]
positional arguments:
bar one of the bars to be frobbled
optional arguments:
-h, --help show this help message and exit
--foo foo the bars before frobbling
Строки help могут включать различные спецификаторы формата, чтобы избежать повторения таких вещей, как имя программы или значение аргумента default. Доступные спецификаторы включают имя программы, %(prog)s и большинство аргументов ключевых слов метода add_argument(), например, %(default)s, %(type)s, и т. д.:
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('bar', nargs='?', type=int, default=42,
... help='the bar to %(prog)s (default: %(default)s)')
>>> parser.print_help()
usage: frobble [-h] [bar]
positional arguments:
bar the bar to frobble (default: 42)
optional arguments:
-h, --help show this help message and exit
Поскольку строка справки поддерживает %-форматирование, если вы хотите, чтобы буквальный символ % появился в строке справки, его необходимо экранировать как %%.
argparse поддерживает отключение записи справки для определенных опций, установив значение help в argparse.SUPPRESS:
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', help=argparse.SUPPRESS)
>>> parser.print_help()
usage: frobble [-h]
optional arguments:
-h, --help show this help message and exit
3.10. псевдоним
Когда ArgumentParser генерирует сообщения справки, ему нужен способ ссылки на каждый ожидаемый аргумент. По умолчанию объекты ArgumentParser используют значение dest в качестве «имени» каждого объекта. По умолчанию для позиционных аргументов действие dest используется непосредственно, а для необязательных аргументов действие dest преобразуется в верхний регистр. Таким образом, один позиционный аргумент с dest='bar' будет упоминаться как bar. Один необязательный аргумент --foo, за которым должна следовать одна строка командной строки, будет упоминаться как FOO. Пример:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage: [-h] [--foo FOO] bar
positional arguments:
bar
optional arguments:
-h, --help show this help message and exit
--foo FOO
Альтернативное имя можно указать с помощью metavar:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage: [-h] [--foo YYY] XXX
positional arguments:
XXX
optional arguments:
-h, --help show this help message and exit
--foo YYY
Обратите внимание, что metavar изменяет только отображаемое имя — имя атрибута в объекте parse_args() всё ещё определяется значением dest.
Различные значения nargs могут привести к использованию псевдонима несколько раз. Передача кортежа в metavar указывает различное отображение для каждого из аргументов:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', nargs=2)
>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
>>> parser.print_help()
usage: PROG [-h] [-x X X] [--foo bar baz]
optional arguments:
-h, --help show this help message and exit
-x X X
--foo bar baz
3.11. dest
Большинство действий ArgumentParser добавляют некоторое значение в качестве атрибута объекта, возвращаемого методом parse_args(). Имя этого атрибута определяется аргументом dest метода add_argument(). Для позиционных аргументов dest обычно передаётся первым аргументом в add_argument():
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')
Для необязательных аргументов значение dest обычно определяется по строкам опций. ArgumentParser генерирует значение dest путём взятия первой длинной строки опции и удаления начальной строки --. Если длинных строк опций не было, значение dest будет получено из первой короткой строки опции путём удаления начального символа -. Любые внутренние символы - будут преобразованы в символы _, чтобы убедиться, что строка является допустимым именем атрибута. Ниже приведены примеры, демонстрирующие это поведение:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-f', '--foo-bar', '--foo')
>>> parser.add_argument('-x', '-y')
>>> parser.parse_args('-f 1 -x 2'.split())
Namespace(foo_bar='1', x='2')
>>> parser.parse_args('--foo 1 -y 2'.split())
Namespace(foo_bar='1', x='2')
dest позволяет предоставить пользовательское имя атрибута:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')
3.12. Классы действий
Классы действий реализуют API действий, вызываемый объект, который возвращает вызываемый объект, обрабатывающий аргументы из командной строки. Любой объект, который соответствует этому API, может быть передан в качестве параметра action в add_argument().
-
class argparse.Action(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)
Объекты Action используются ArgumentParser для представления информации, необходимой для разбора одного аргумента из одной или нескольких строк из командной строки. Класс Action должен принимать два позиционных аргумента плюс любые аргументы ключевых слов, переданные в ArgumentParser.add_argument(), за исключением самого action.
Объекты Action (или возвращаемое значение любого вызываемого объекта для параметра action должны иметь определённые атрибуты «dest», «option_strings», «default», «type», «required», «help» и т. д. Самый простой способ гарантировать, что эти атрибуты определены, — это вызвать Action.__init__.
Объекты Action должны быть вызываемыми, поэтому подклассы должны переопределять метод __call__, который должен принимать четыре параметра:
-
parser- Объект ArgumentParser, содержащий данное действие. -
namespace- ОбъектNamespace, который будет возвращён методомparse_args(). Большинство действий добавляют атрибут в этот объект, используяsetattr(). -
values- Соответствующие аргументы командной строки, с применёнными преобразованиями типов. Преобразования типов задаются ключевым аргументом type в методеadd_argument(). -
option_string- Строка опции, которая использовалась для вызова данного действия. Аргументoption_stringнеобязателен и отсутствует, если действие связано с позиционным аргументом.
Метод __call__ может выполнять произвольные действия, но обычно устанавливает атрибуты в объекте namespace на основе dest и values.
4. Метод parse_args()
-
ArgumentParser.parse_args(args=None, namespace=None) -
Преобразует строки аргументов в объекты и присваивает их в качестве атрибутов пространства имён. Возвращает заполненное пространство имён.
Предыдущие вызовы метода
add_argument()определяют, какие именно объекты создаются и как они присваиваются. Подробнее см. документацию дляadd_argument().По умолчанию, строки аргументов берутся из
sys.argv, и для атрибутов создаётся новый пустой объектNamespace.
4.1. Синтаксис значений опций
Метод parse_args() поддерживает несколько способов указания значения опции (если оно требуется). В самом простом случае опция и её значение передаются в качестве двух отдельных аргументов:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('--foo')
>>> parser.parse_args(['-x', 'X'])
Namespace(foo=None, x='X')
>>> parser.parse_args(['--foo', 'FOO'])
Namespace(foo='FOO', x=None)
Для длинных опций (с именами длиннее одного символа) опция и значение также могут передаваться как один аргумент командной строки, используя = в качестве разделителя:
>>> parser.parse_args(['--foo=FOO']) Namespace(foo='FOO', x=None)
Для коротких опций (состоящих только из одного символа) опция и её значение могут быть объединены:
>>> parser.parse_args(['-xX']) Namespace(foo=None, x='X')
Несколько коротких опций могут быть объединены вместе, используя только один - префикс, при условии, что только последняя опция (или ни одна) требует значения:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', action='store_true')
>>> parser.add_argument('-y', action='store_true')
>>> parser.add_argument('-z')
>>> parser.parse_args(['-xyzZ'])
Namespace(x=True, y=True, z='Z')
4.2. Некорректные аргументы
При разборе командной строки, метод parse_args() проверяет множество ошибок, включая неоднозначные опции, некорректные типы, некорректные опции, неверное количество позиционных аргументов и т.д. При обнаружении такой ошибки, он завершается и выводит ошибку вместе с сообщением об использовании:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', nargs='?')
>>> # invalid type
>>> parser.parse_args(['--foo', 'spam'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: argument --foo: invalid int value: 'spam'
>>> # invalid option
>>> parser.parse_args(['--bar'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: no such option: --bar
>>> # wrong number of arguments
>>> parser.parse_args(['spam', 'badger'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: extra arguments found: badger
4.3. Аргументы, содержащие -
Метод parse_args() пытается сообщать об ошибках, когда пользователь явно ошибается, но некоторые ситуации являются внутренне неоднозначными. Например, аргумент командной строки -1 может быть попыткой указать опцию или попыткой указать позиционный аргумент. Метод parse_args() осторожен здесь: позиционные аргументы могут начинаться только с -, если они похожи на отрицательные числа, и в парсере нет опций, похожих на отрицательные числа:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('foo', nargs='?')
>>> # no negative number options, so -1 is a positional argument
>>> parser.parse_args(['-x', '-1'])
Namespace(foo=None, x='-1')
>>> # no negative number options, so -1 and -5 are positional arguments
>>> parser.parse_args(['-x', '-1', '-5'])
Namespace(foo='-5', x='-1')
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-1', dest='one')
>>> parser.add_argument('foo', nargs='?')
>>> # negative number options present, so -1 is an option
>>> parser.parse_args(['-1', 'X'])
Namespace(foo=None, one='X')
>>> # negative number options present, so -2 is an option
>>> parser.parse_args(['-2'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: no such option: -2
>>> # negative number options present, so both -1s are options
>>> parser.parse_args(['-1', '-1'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: argument -1: expected one argument
Если у вас есть позиционные аргументы, которые должны начинаться с - и не похожи на отрицательные числа, вы можете вставить псевдоаргумент '--', который сообщает методу parse_args(), что всё после него является позиционным аргументом:
>>> parser.parse_args(['--', '-f']) Namespace(foo='-f', one=None)
4.4. Сокращения аргументов (сопоставление по префиксу)
Метод parse_args() по умолчанию допускает сокращение длинных опций до префикса, если сокращение является однозначным (префикс соответствует единственной опции):
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-bacon')
>>> parser.add_argument('-badger')
>>> parser.parse_args('-bac MMM'.split())
Namespace(bacon='MMM', badger=None)
>>> parser.parse_args('-bad WOOD'.split())
Namespace(bacon=None, badger='WOOD')
>>> parser.parse_args('-ba BA'.split())
usage: PROG [-h] [-bacon BACON] [-badger BADGER]
PROG: error: ambiguous option: -ba could match -badger, -bacon
Возникает ошибка для аргументов, которые могут соответствовать нескольким опциям. Эту функцию можно отключить, установив allow_abbrev в False.
4.5. За пределами sys.argv
Иногда может быть полезно, чтобы ArgumentParser парсил аргументы, отличные от аргументов sys.argv. Этого можно добиться, передав список строк методу parse_args(). Это полезно для тестирования в интерактивном режиме:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument( ... 'integers', metavar='int', type=int, choices=range(10), ... nargs='+', help='an integer in the range 0..9') >>> parser.add_argument( ... '--sum', dest='accumulate', action='store_const', const=sum, ... default=max, help='sum the integers (default: find the max)') >>> parser.parse_args(['1', '2', '3', '4']) Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4]) >>> parser.parse_args(['1', '2', '3', '4', '--sum']) Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])
4.6. Объект Namespace
-
class argparse.Namespace -
Простой класс, используемый по умолчанию методом
parse_args()для создания объекта, содержащего атрибуты, и его возвращения.
Этот класс специально прост, это подкласс object с удобочитаемым строковым представлением. Если вы предпочитаете иметь представление об атрибутах в виде словаря, можно использовать стандартный Python-идиому vars():
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}
Также может быть полезно, чтобы ArgumentParser присваивал атрибуты уже существующему объекту, а не новому объекту Namespace. Этого можно добиться, указав ключевой аргумент namespace=:
>>> class C:
... pass
...
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
>>> c.foo
'BAR'
5. Другие утилиты
5.1. Подкоманды
-
ArgumentParser.add_subparsers([title][, description][, prog][, parser_class][, action][, option_string][, dest][, help][, metavar]) -
Многие программы разделяют свою функциональность на ряд подкоманд, например, программа
svnможет вызывать подкоманды, такие какsvn checkout,svn update, иsvn commit. Такое разделение функциональности может быть особенно полезно, когда программа выполняет несколько различных функций, для которых требуются разные типы аргументов командной строки.ArgumentParserподдерживает создание таких подкоманд с помощью методаadd_subparsers(). Методadd_subparsers()обычно вызывается без аргументов и возвращает специальный объект действия. Этот объект имеет один метод,add_parser(), который принимает имя команды и любые аргументы конструктораArgumentParser, и возвращает объектArgumentParser, который можно изменять обычным образом.Описание параметров:
- title - заголовок группы подпарсеров в выводе справки; по умолчанию «подкоманды», если описание предоставлено, в противном случае используется заголовок для позиционных аргументов
- description - описание группы подпарсеров в выводе справки, по умолчанию
None - prog - информация об использовании, которая будет отображаться со справкой по подкоманде, по умолчанию имя программы и любые позиционные аргументы перед аргументом подпарсера
- parser_class - класс, который будет использоваться для создания экземпляров подпарсеров, по умолчанию класс текущего парсера (например, ArgumentParser)
- action - базовый тип действия, который будет выполнен, когда этот аргумент встретится в командной строке
-
dest - имя атрибута, в котором будет храниться имя подкоманды; по умолчанию
Noneи значение не сохраняется -
help - справка по группе подпарсеров в выводе справки, по умолчанию
None -
metavar - строка, представляющая доступные подкоманды в справке; по умолчанию это
Noneи представляет подкоманды в виде {cmd1, cmd2, ..}
Примеры использования:
>>> # create the top-level parser >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo', action='store_true', help='foo help') >>> subparsers = parser.add_subparsers(help='sub-command help') >>> >>> # create the parser for the "a" command >>> parser_a = subparsers.add_parser('a', help='a help') >>> parser_a.add_argument('bar', type=int, help='bar help') >>> >>> # create the parser for the "b" command >>> parser_b = subparsers.add_parser('b', help='b help') >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help') >>> >>> # parse some argument lists >>> parser.parse_args(['a', '12']) Namespace(bar=12, foo=False) >>> parser.parse_args(['--foo', 'b', '--baz', 'Z']) Namespace(baz='Z', foo=True)Обратите внимание, что объект, возвращаемый
parse_args(), будет содержать только атрибуты для основного парсера и подпарсера, который был выбран командной строкой (а не любые другие подпарсеры). Итак, в приведенном выше примере, когда указана командаa, присутствуют только атрибутыfooиbar, а когда указана командаb, присутствуют только атрибутыfooиbaz.Аналогично, когда запрашивается сообщение справки от подпарсера, будет напечатана только справка для этого конкретного парсера. Сообщение справки не будет включать сообщения родительского или родственного парсера. (Сообщение справки для каждой подкоманды подпарсера, однако, можно предоставить, передав аргумент
help=вadd_parser()как показано выше.)>>> parser.parse_args(['--help']) usage: PROG [-h] [--foo] {a,b} ... positional arguments: {a,b} sub-command help a a help b b help optional arguments: -h, --help show this help message and exit --foo foo help >>> parser.parse_args(['a', '--help']) usage: PROG a [-h] bar positional arguments: bar bar help optional arguments: -h, --help show this help message and exit >>> parser.parse_args(['b', '--help']) usage: PROG b [-h] [--baz {X,Y,Z}] optional arguments: -h, --help show this help message and exit --baz {X,Y,Z} baz helpМетод
add_subparsers()также поддерживает ключевые аргументыtitleиdescription. При наличии любого из них команды подпарсера будут отображаться в своей собственной группе в выводе справки. Например:>>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers(title='subcommands', ... description='valid subcommands', ... help='additional help') >>> subparsers.add_parser('foo') >>> subparsers.add_parser('bar') >>> parser.parse_args(['-h']) usage: [-h] {foo,bar} ... optional arguments: -h, --help show this help message and exit subcommands: valid subcommands {foo,bar} additional helpКроме того,
add_parserподдерживает дополнительный аргументaliases, который позволяет использовать несколько строк для ссылки на один и тот же подпарсер. В этом примере, как и вsvn,coиспользуется как сокращение дляcheckout.>>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers() >>> checkout = subparsers.add_parser('checkout', aliases=['co']) >>> checkout.add_argument('foo') >>> parser.parse_args(['co', 'bar']) Namespace(foo='bar')Один из особенно эффективных способов обработки подкоманд — объединить использование метода
add_subparsers()с вызовамиset_defaults()таким образом, чтобы каждый подпарсер знал, какую функцию Python он должен выполнить. Например:>>> # sub-command functions >>> def foo(args): ... print(args.x * args.y) ... >>> def bar(args): ... print('((%s))' % args.z) ... >>> # create the top-level parser >>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers() >>> >>> # create the parser for the "foo" command >>> parser_foo = subparsers.add_parser('foo') >>> parser_foo.add_argument('-x', type=int, default=1) >>> parser_foo.add_argument('y', type=float) >>> parser_foo.set_defaults(func=foo) >>> >>> # create the parser for the "bar" command >>> parser_bar = subparsers.add_parser('bar') >>> parser_bar.add_argument('z') >>> parser_bar.set_defaults(func=bar) >>> >>> # parse the args and call whatever function was selected >>> args = parser.parse_args('foo 1 -x 2'.split()) >>> args.func(args) 2.0 >>> >>> # parse the args and call whatever function was selected >>> args = parser.parse_args('bar XYZYX'.split()) >>> args.func(args) ((XYZYX))Таким образом, вы можете позволить
parse_args()выполнить работу по вызову соответствующей функции после завершения обработки аргументов. Связывание функций с действиями таким образом, как правило, является самым простым способом обработки различных действий для каждого из ваших подпарсеров. Однако, если необходимо проверить имя подпарсера, который был вызван, аргументdestв вызовеadd_subparsers()сработает:>>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers(dest='subparser_name') >>> subparser1 = subparsers.add_parser('1') >>> subparser1.add_argument('-x') >>> subparser2 = subparsers.add_parser('2') >>> subparser2.add_argument('y') >>> parser.parse_args(['2', 'frobble']) Namespace(subparser_name='2', y='frobble')
5.2. Объекты FileType
-
class argparse.FileType(mode='r', bufsize=-1, encoding=None, errors=None) -
Фабрика
FileTypeсоздает объекты, которые можно передать в аргумент type методаArgumentParser.add_argument(). Аргументы, имеющие объектыFileTypeв качестве своего типа, откроют аргументы командной строки как файлы с запрошенными режимами, размерами буфера, кодировками и обработкой ошибок (см. функциюopen()для получения более подробной информации):>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--raw', type=argparse.FileType('wb', 0)) >>> parser.add_argument('out', type=argparse.FileType('w', encoding='UTF-8')) >>> parser.parse_args(['--raw', 'raw.dat', 'file.txt']) Namespace(out=<_io.TextIOWrapper name='file.txt' mode='w' encoding='UTF-8'>, raw=<_io.FileIO name='raw.dat' mode='wb'>)Объекты FileType понимают псевдоаргумент
'-'и автоматически преобразуют его вsys.stdinдля читаемых объектовFileTypeиsys.stdoutдля записываемых объектовFileType:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('infile', type=argparse.FileType('r')) >>> parser.parse_args(['-']) Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)Добавлен в версии 3.4: Ключевые аргументы encodings и errors.
5.3. Группы аргументов
-
ArgumentParser.add_argument_group(title=None, description=None) -
По умолчанию,
ArgumentParserгруппирует аргументы командной строки в «позиционные аргументы» и «необязательные аргументы» при отображении сообщений справки. Когда существует лучшая концептуальная группировка аргументов, отличная от этой стандартной, соответствующие группы могут быть созданы с помощью методаadd_argument_group():>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False) >>> group = parser.add_argument_group('group') >>> group.add_argument('--foo', help='foo help') >>> group.add_argument('bar', help='bar help') >>> parser.print_help() usage: PROG [--foo FOO] bar group: bar bar help --foo FOO foo helpМетод
add_argument_group()возвращает объект группы аргументов, который имеет методadd_argument(), подобно обычномуArgumentParser. Когда аргумент добавляется в группу, парсер обрабатывает его так же, как обычный аргумент, но отображает аргумент в отдельной группе для сообщений справки. Методadd_argument_group()принимает аргументы title и description, которые можно использовать для настройки этого отображения:>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False) >>> group1 = parser.add_argument_group('group1', 'group1 description') >>> group1.add_argument('foo', help='foo help') >>> group2 = parser.add_argument_group('group2', 'group2 description') >>> group2.add_argument('--bar', help='bar help') >>> parser.print_help() usage: PROG [--bar BAR] foo group1: group1 description foo foo help group2: group2 description --bar BAR bar helpОбратите внимание, что все аргументы, не входящие в ваши пользовательские группы, в конечном итоге попадут в обычные разделы «позиционные аргументы» и «необязательные аргументы».
5.4. Взаимоисключение
-
ArgumentParser.add_mutually_exclusive_group(required=False) -
Создать группу взаимоисключающих аргументов.
argparseбудет гарантировать, что только один из аргументов в группе взаимоисключения был присутствовал в командной строке:>>> parser = argparse.ArgumentParser(prog='PROG') >>> group = parser.add_mutually_exclusive_group() >>> group.add_argument('--foo', action='store_true') >>> group.add_argument('--bar', action='store_false') >>> parser.parse_args(['--foo']) Namespace(bar=True, foo=True) >>> parser.parse_args(['--bar']) Namespace(bar=False, foo=False) >>> parser.parse_args(['--foo', '--bar']) usage: PROG [-h] [--foo | --bar] PROG: error: argument --bar: not allowed with argument --fooМетод
add_mutually_exclusive_group()также принимает аргумент required, чтобы указать, что по крайней мере один из взаимоисключающих аргументов является обязательным:>>> parser = argparse.ArgumentParser(prog='PROG') >>> group = parser.add_mutually_exclusive_group(required=True) >>> group.add_argument('--foo', action='store_true') >>> group.add_argument('--bar', action='store_false') >>> parser.parse_args([]) usage: PROG [-h] (--foo | --bar) PROG: error: one of the arguments --foo --bar is requiredОбратите внимание, что в настоящее время группы взаимоисключающих аргументов не поддерживают аргументы title и description метода
add_argument_group().
5.5. Значения по умолчанию парсера
-
ArgumentParser.set_defaults(**kwargs) -
В большинстве случаев атрибуты объекта, возвращаемого
parse_args(), полностью определяются путем проверки аргументов командной строки и действий аргументов.set_defaults()позволяет добавить дополнительные атрибуты, которые определяются без какой-либо проверки командной строки:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('foo', type=int) >>> parser.set_defaults(bar=42, baz='badger') >>> parser.parse_args(['736']) Namespace(bar=42, baz='badger', foo=736)Обратите внимание, что значения по умолчанию на уровне парсера всегда переопределяют значения по умолчанию на уровне аргументов:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default='bar') >>> parser.set_defaults(foo='spam') >>> parser.parse_args([]) Namespace(foo='spam')Значения по умолчанию на уровне парсера могут быть особенно полезны при работе с несколькими парсерами. См. метод
add_subparsers()для примера этого типа.
-
ArgumentParser.get_default(dest) -
Получить значение по умолчанию для атрибута именованного пространства, установленного либо методом
add_argument(), либоset_defaults():>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default='badger') >>> parser.get_default('foo') 'badger'
5.6. Вывод справки
В большинстве типичных приложений parse_args() будет заниматься форматированием и выводом сообщений об использовании или об ошибках. Однако доступны несколько методов форматирования:
-
ArgumentParser.print_usage(file=None) -
Вывести краткое описание того, как следует вызывать
ArgumentParserв командной строке. Если file равноNone, предполагается использованиеsys.stdout.
-
ArgumentParser.print_help(file=None) -
Вывести сообщение справки, включая использование программы и информацию об аргументах, зарегистрированных в
ArgumentParser. Если file равноNone, предполагается использованиеsys.stdout.
Также существуют варианты этих методов, которые просто возвращают строку вместо её вывода:
-
ArgumentParser.format_usage() -
Возвращает строку, содержащую краткое описание того, как следует вызывать
ArgumentParserв командной строке.
-
ArgumentParser.format_help() -
Возвращает строку, содержащую сообщение справки, включая использование программы и информацию об аргументах, зарегистрированных в
ArgumentParser.
5.7. Частичный разбор
-
ArgumentParser.parse_known_args(args=None, namespace=None)
Иногда скрипту требуется проанализировать только несколько аргументов командной строки, передав оставшиеся аргументы другому скрипту или программе. В таких случаях может быть полезен метод parse_known_args(). Он работает очень похоже на parse_args(), за исключением того, что не генерирует ошибку при наличии дополнительных аргументов. Вместо этого он возвращает кортеж из двух элементов: заполненный экземпляр и список оставшихся строковых аргументов.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('bar')
>>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
(Namespace(bar='BAR', foo=True), ['--badger', 'spam'])
Предупреждение
Правила сопоставления по префиксу применяются к parse_known_args(). Парсер может обработать опцию, даже если она является лишь префиксом одной из известных опций, а не оставить её в списке оставшихся аргументов.
5.8. Настройка разбора из файлов
-
ArgumentParser.convert_arg_line_to_args(arg_line) -
Аргументы, которые считываются из файла (см. параметр fromfile_prefix_chars конструктора
ArgumentParser), считываются по одному аргументу на строку.convert_arg_line_to_args()можно переопределить для более сложного чтения.Этот метод принимает один аргумент arg_line, который представляет собой строку, считанную из файла аргументов. Он возвращает список аргументов, разобранных из этой строки. Метод вызывается один раз на каждую строку, считанную из файла аргументов, в порядке следования.
Полезное переопределение этого метода — то, которое рассматривает каждое разделенное пробелом слово как аргумент. Следующий пример демонстрирует, как это сделать:
class MyArgumentParser(argparse.ArgumentParser): def convert_arg_line_to_args(self, arg_line): return arg_line.split()
5.9. Методы завершения
-
ArgumentParser.exit(status=0, message=None) -
Этот метод завершает выполнение программы, выходя с указанным status и, если предоставлено, выводит message перед этим.
-
ArgumentParser.error(message) -
Этот метод выводит сообщение об использовании, включая message, в стандартный поток ошибок и завершает программу со статусом 2.
6. Обновление кода optparse
Изначально модуль argparse пытался сохранить совместимость с optparse. Однако optparse было сложно расширять прозрачно, особенно с изменениями, необходимыми для поддержки новых спецификаторов nargs= и улучшенных сообщений об использовании. Когда большая часть кода optparse была либо скопирована, либо произведено его переписывание с использованием патчей, оказалось непрактичным поддерживать обратную совместимость.
Модуль argparse улучшает стандартный модуль библиотеки optparse множеством способов, включая:
- Обработку позиционных аргументов.
- Поддержку подкоманд.
- Возможность альтернативных префиксов опций, таких как
+и/. - Обработку аргументов типа «ноль или более» и «один или более».
- Генерацию более информативных сообщений об использовании.
- Предоставление гораздо более простого интерфейса для пользовательских
typeиaction.
Частичный путь миграции от optparse к argparse:
- Замените все вызовы
optparse.OptionParser.add_option()вызовамиArgumentParser.add_argument(). - Замените
(options, args) = parser.parse_args()наargs = parser.parse_args()и добавьте дополнительные вызовыArgumentParser.add_argument()для позиционных аргументов. Имейте в виду, что то, что ранее называлосьoptions, теперь в контекстеargparseназываетсяargs. - Замените действия обратных вызовов и аргументы
callback_*на аргументыtypeилиaction. - Замените строковые имена для аргументов
typeсоответствующими объектами типов (например, int, float, complex и т.д.). - Замените
optparse.ValuesнаNamespaceиoptparse.OptionErrorиoptparse.OptionValueErrorнаArgumentError. - Замените строки с неявными аргументами, такие как
%defaultили%prog, стандартным синтаксисом Python для использования словарей для форматирования строк, то есть,%(default)sи%(prog)s. - Замените аргумент конструктора OptionParser
versionвызовомparser.add_argument('--version', action='version', version='<the version>').
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/argparse.html