Содержание страницы
16.4. argparse – Парсер для параметров командной строки, аргументов и подкоманд¶argparse – Parser for command-line options, arguments and sub-commands
Новое в версии 3.2.
Исходный код: Lib/argparse.py
Модуль argparse упрощает создание удобных интерфейсов командной строки. Программа определяет, какие аргументы ей нужны, а argparse разбирается, как извлечь их из sys.argv. Модуль argparse также автоматически генерирует сообщения справки и использования, а также выдает ошибки, когда пользователь передает программе недопустимые аргументы.
16.4.1. Пример¶Example
Следующий код представляет собой программу на 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'
В следующих разделах этот пример разбирается подробно.
16.4.1.1. Создание парсера¶Creating a parser
Первый шаг при использовании argparse – создать объект ArgumentParser:
>>> parser = argparse.ArgumentParser(description='Process some integers.')
Объект ArgumentParser будет содержать всю информацию, необходимую для синтаксического разбора командной строки в типы данных Python.
16.4.1.2. Добавление аргументов¶Adding arguments
Наполнение объекта 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(), если не был.
16.4.1.3. Разбор аргументов¶Parsing arguments
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.
16.4.2. Объекты ArgumentParser¶ArgumentParser objects
- 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)¶
Создаёт новый объект 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 в синтаксический анализатор (по умолчанию: True)
В следующих разделах описывается, как используется каждый из этих параметров.
16.4.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
16.4.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 доступен для подстановки имени программы в сообщения об использовании.
16.4.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.
16.4.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.
16.4.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=. Если изменить родительские парсеры после создания дочернего, эти изменения не отразятся в дочернем.
16.4.2.6. formatter_class¶
Объекты ArgumentParser позволяют настраивать форматирование справки с помощью указания альтернативного класса форматирования. В настоящее время существует четыре таких класса:
- class argparse.RawDescriptionHelpFormatter¶
- class argparse.RawTextHelpFormatter¶
- class argparse.ArgumentDefaultsHelpFormatter¶
- class argparse.MetavarTypeHelpFormatter¶
RawDescriptionHelpFormatter и RawTextHelpFormatter дают больше контроля над отображением текстовых описаний. По умолчанию объекты ArgumentParser переносят строки в тексте description и epilog в сообщениях справки командной строки:
>>> 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= указывает, что description и epilog уже правильно отформатированы и не должны переноситься по строкам:
>>> 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 использует имя аргумента type для каждого аргумента в качестве отображаемого имени его значений (вместо использования 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
16.4.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 будут запрещены.
16.4.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, то есть аргументы никогда не будут рассматриваться как ссылки на файлы.
16.4.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()
16.4.2.10. 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
Иногда (например, при использовании parents) может быть полезно просто переопределить любые старые аргументы с той же строкой опции. Чтобы получить такое поведение, можно передать значение '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.
16.4.2.11. 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
16.4.3. Метод add_argument()¶The add_argument() method
- ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])¶
Определяет, как должен разбираться один аргумент командной строки. Каждый параметр подробно описан ниже, а кратко они таковы:
- имя или флаги – Имя или список строк параметров, например foo или -f, --foo.
- action – базовый тип действия, которое выполняется при встрече этого аргумента в командной строке.
- nargs – количество аргументов командной строки, которое должно быть потреблено.
- const – постоянное значение, требуемое некоторыми значениями action и nargs.
- default – Значение, создаваемое, если аргумент отсутствует в командной строке.
- type – тип, в который следует преобразовать аргумент командной строки.
- choices – Контейнер допустимых значений для аргумента.
- required – может ли параметр командной строки быть опущен (только для опциональных параметров).
- help – краткое описание того, что делает аргумент.
- metavar – имя аргумента в сообщениях об использовании.
- dest – Имя атрибута, который будет добавлен к объекту, возвращаемому parse_args().
В следующих разделах описывается, как используется каждый из этих параметров.
16.4.3.1. name или flags¶name or flags
Метод 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
16.4.3.2. action¶
Объекты ArgumentParser связывают аргументы командной строки с действиями. Эти действия могут делать почти что угодно с связанными с ними аргументами командной строки, хотя большинство действий просто добавляют атрибут к объекту, возвращаемому parse_args(). Аргумент-ключевое слово action определяет, как должны обрабатываться аргументы командной строки. Предоставляются следующие действия:
'store' – Просто сохраняет значение аргумента. Это действие по умолчанию. Например:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> parser.parse_args('--foo 1'.split()) Namespace(foo='1')
'store_const' – Сохраняет значение, указанное аргументом-ключевым словом const. (Обратите внимание, что аргумент-ключевое слово const по умолчанию равен довольно бесполезному None.) Действие 'store_const' чаще всего используется с необязательными аргументами, задающими какой-либо флаг. Например:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_const', const=42) >>> parser.parse_args('--foo'.split()) Namespace(foo=42)
'store_true' и 'store_false' – Сохраняют значения True и False соответственно. Это частные случаи 'store_const'. Например:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_true') >>> parser.add_argument('--bar', action='store_false') >>> parser.parse_args('--foo --bar'.split()) Namespace(bar=False, foo=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'.split()) Namespace(verbose=3)
'help' – Выводит полное сообщение справки для всех параметров текущего парсера и завершает работу. По умолчанию действие 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.
16.4.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'.split()) Namespace(bar='XX', foo='YY') >>> parser.parse_args('XX --foo'.split()) Namespace(bar='XX', foo='c') >>> parser.parse_args(''.split()) 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'.split()) Namespace(foo=['a', 'b']) >>> parser.parse_args(''.split()) 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. Обычно это означает, что будет потреблен один аргумент командной строки и создан один элемент (не список).
16.4.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 для примеров.
Аргумент-ключевое слово const по умолчанию равен None.
16.4.3.5. default¶
Все необязательные аргументы и некоторые позиционные аргументы могут быть опущены в командной строке. Аргумент-ключевое слово default функции add_argument(), значение которого по умолчанию равно None, определяет, какое значение следует использовать, если аргумент командной строки отсутствует. Для необязательных аргументов значение default используется, когда строка параметра не присутствовала в командной строке:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args('--foo 2'.split())
Namespace(foo='2')
>>> parser.parse_args(''.split())
Namespace(foo=42)
Если значением default является строка, анализатор разбирает его так, как если бы это был аргумент командной строки. В частности, анализатор применяет любой аргумент преобразования type, если он указан, перед установкой атрибута в возвращаемом значении 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'.split())
Namespace(foo='a')
>>> parser.parse_args(''.split())
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')
16.4.3.6. type¶
По умолчанию объекты 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= функции 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'.split())
Namespace(foo=9)
>>> parser.parse_args('7'.split())
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'.split())
Namespace(foo=7)
>>> parser.parse_args('11'.split())
usage: PROG [-h] {5,6,7,8,9}
PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
См. раздел choices для получения дополнительных сведений.
16.4.3.7. choices¶
Some command-line arguments should be selected from a restricted set of values. These can be handled by passing a container object as the choices keyword argument to add_argument(). When the command line is parsed, argument values will be checked, and an error message will be displayed if the argument was not one of the acceptable values:
>>> 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 проверяется после всех преобразований типа type, поэтому тип объектов в choices должен соответствовать указанному type:
>>> 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)
Any object that supports the in operator can be passed as the choices value, so dict objects, set objects, custom containers, etc. are all supported.
16.4.3.8. required¶
In general, the argparse module assumes that flags like -f and --bar indicate optional arguments, which can always be omitted at the command line. To make an option required, True can be specified for the required= keyword argument to 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() сообщит об ошибке, если эта опция отсутствует в командной строке.
Примечание
Обязательные опции обычно считаются дурным тоном, поскольку пользователи ожидают, что опции будут необязательными, поэтому их следует по возможности избегать.
16.4.3.9. help¶
Значение 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'.split())
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
16.4.3.10. мета-переменная¶metavar
Когда 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. Передача кортежа в 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
16.4.3.11. dest¶
Most ArgumentParser actions add some value as an attribute of the object returned by parse_args(). The name of this attribute is determined by the dest keyword argument of add_argument(). For positional argument actions, dest is normally supplied as the first argument to add_argument():
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args('XXX'.split())
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')
16.4.3.12. Классы действий¶Action classes
Классы действий реализуют API Action – вызываемый объект, который возвращает вызываемый объект, обрабатывающий аргументы командной строки. Любой объект, следующий этому API, может быть передан в качестве параметра action функции add_argument().
- 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.
16.4.4. Метод parse_args()¶The parse_args() method
- ArgumentParser.parse_args(args=None, namespace=None)¶
Преобразует строки аргументов в объекты и назначает их в качестве атрибутов пространства имён. Возвращает заполненное пространство имён.
Предыдущие вызовы add_argument() определяют, какие именно объекты создаются и как они назначаются. Подробнее см. документацию к add_argument().
По умолчанию строки аргументов берутся из sys.argv, и создаётся новый пустой объект Namespace для атрибутов.
16.4.4.1. Синтаксис значений опций¶Option value syntax
Метод parse_args() поддерживает несколько способов указания значения опции (если она принимает значение). В простейшем случае опция и её значение передаются как два отдельных аргумента:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('--foo')
>>> parser.parse_args('-x X'.split())
Namespace(foo=None, x='X')
>>> parser.parse_args('--foo FOO'.split())
Namespace(foo='FOO', x=None)
Для длинных параметров (с именами длиннее одного символа) параметр и значение могут быть переданы как один аргумент командной строки, используя = для их разделения:
>>> parser.parse_args('--foo=FOO'.split())
Namespace(foo='FOO', x=None)
Для коротких опций (опции длиной в один символ) опция и её значение могут быть объединены:
>>> parser.parse_args('-xX'.split())
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'.split())
Namespace(x=True, y=True, z='Z')
16.4.4.2. Недопустимые аргументы¶Invalid arguments
При разборе командной строки parse_args() проверяет на наличие различных ошибок, включая неоднозначные опции, недопустимые типы, неверные опции, неправильное количество позиционных аргументов и т.д. Когда такая ошибка обнаруживается, он завершает работу и выводит сообщение об ошибке вместе с сообщением об использовании:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', nargs='?')
>>> # недопустимый тип
>>> parser.parse_args(['--foo', 'spam'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: argument --foo: invalid int value: 'spam'
>>> # недопустимая опция
>>> parser.parse_args(['--bar'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: no such option: --bar
>>> # неверное количество аргументов
>>> parser.parse_args(['spam', 'badger'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: extra arguments found: badger
16.4.4.3. Аргументы, содержащие -¶Arguments containing -
Метод parse_args() старается выдавать ошибки всякий раз, когда пользователь явно допустил ошибку, но некоторые ситуации по своей сути неоднозначны. Например, аргумент командной строки -1 может быть как попыткой указать опцию, так и попыткой передать позиционный аргумент. Метод parse_args() в этом случае действует осторожно: позиционные аргументы могут начинаться с - только если они выглядят как отрицательные числа и в синтаксическом анализаторе нет опций, которые выглядят как отрицательные числа:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('foo', nargs='?')
>>> # нет опций с отрицательными числами, поэтому -1 – позиционный аргумент
>>> parser.parse_args(['-x', '-1'])
Namespace(foo=None, x='-1')
>>> # нет опций с отрицательными числами, поэтому -1 и -5 – позиционные аргументы
>>> 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='?')
>>> # опции с отрицательными числами присутствуют, поэтому -1 – это опция
>>> parser.parse_args(['-1', 'X'])
Namespace(foo=None, one='X')
>>> # опции с отрицательными числами присутствуют, поэтому -2 – это опция
>>> parser.parse_args(['-2'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: no such option: -2
>>> # опции с отрицательными числами присутствуют, поэтому обе -1 – это опции
>>> 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)
16.4.4.4. Сокращения аргументов (совпадение по префиксу)¶Argument abbreviations (prefix matching)
Метод 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
Для аргументов, которые могут соответствовать более чем одной опции, выдаётся ошибка.
16.4.4.5. За пределами sys.argv¶Beyond sys.argv
Sometimes it may be useful to have an ArgumentParser parse arguments other than those of sys.argv. This can be accomplished by passing a list of strings to parse_args(). This is useful for testing at the interactive prompt:
>>> 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'.split())
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])
16.4.4.6. Объект Namespace¶The Namespace object
- 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'
16.4.5. Другие утилиты¶Other utilities
16.4.5.1. Подкоманды¶Sub-commands
- 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 – заголовок для группы подпарсеров в выводе справки; по умолчанию «subcommands», если указано описание, в противном случае используется заголовок для позиционных аргументов.
- description – описание для группы подпарсеров в выводе справки, по умолчанию None
- prog – информация об использовании, которая будет отображаться в справке подкоманды; по умолчанию – имя программы и любые позиционные аргументы перед аргументом подпарсера
- parser_class – класс, который будет использоваться для создания экземпляров подпарсера; по умолчанию – класс текущего парсера (например, ArgumentParser)
- dest – имя атрибута, в котором будет сохранено имя подкоманды; по умолчанию None, и значение не сохраняется
- help – справка для группы подпарсеров в выводе справки; по умолчанию None
- metavar – строка, представляющая доступные подкоманды в справке; по умолчанию None, и подкоманды отображаются в виде {cmd1, cmd2, ..}
Пример использования:
>>> # создать парсер верхнего уровня >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo', action='store_true', help='foo help') >>> subparsers = parser.add_subparsers(help='sub-command help') >>> >>> # создать парсер для команды "a" >>> parser_a = subparsers.add_parser('a', help='a help') >>> parser_a.add_argument('bar', type=int, help='bar help') >>> >>> # создать парсер для команды "b" >>> parser_b = subparsers.add_parser('b', help='b help') >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help') >>> >>> # разобрать некоторые списки аргументов >>> 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 он должен выполнять. Например:
>>> # функции подкоманд >>> def foo(args): ... print(args.x * args.y) ... >>> def bar(args): ... print('((%s))' % args.z) ... >>> # создать парсер верхнего уровня >>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers() >>> >>> # создать парсер для команды "foo" >>> 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) >>> >>> # создать парсер для команды "bar" >>> parser_bar = subparsers.add_parser('bar') >>> parser_bar.add_argument('z') >>> parser_bar.set_defaults(func=bar) >>> >>> # разобрать аргументы и вызвать выбранную функцию >>> args = parser.parse_args('foo 1 -x 2'.split()) >>> args.func(args) 2.0 >>> >>> # разобрать аргументы и вызвать выбранную функцию >>> 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')
16.4.5.2. Объекты FileType¶FileType objects
- class argparse.FileType(mode='r', bufsize=None)¶
Фабрика FileType создаёт объекты, которые можно передать в аргумент type функции ArgumentParser.add_argument(). Аргументы, у которых в качестве типа указаны объекты FileType, будут открывать переданные в командной строке имена файлов как файлы с указанными режимами и размерами буфера:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--output', type=argparse.FileType('wb', 0)) >>> parser.parse_args(['--output', 'out']) Namespace(output=<_io.BufferedWriter name='out'>)
Объекты 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'>)
16.4.5.3. Группы аргументов¶Argument groups
- 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
Обратите внимание, что любые аргументы, не входящие в ваши пользовательские группы, окажутся обратно в обычных разделах «позиционные аргументы» и «опциональные аргументы».
16.4.5.4. Взаимное исключение¶Mutual exclusion
- 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().
16.4.5.5. Значения по умолчанию анализатора¶Parser defaults
- 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'
16.4.5.6. Вывод справки¶Printing help
В большинстве типичных приложений 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.
16.4.5.7. Частичный разбор¶Partial parsing
- 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(). Синтаксический анализатор может использовать опцию, даже если она является лишь префиксом одной из известных опций, вместо того чтобы оставлять её в списке оставшихся аргументов.
16.4.5.8. Настройка разбора файлов¶Customizing file parsing
- ArgumentParser.convert_arg_line_to_args(arg_line)¶
Аргументы, которые считываются из файла (см. именованный аргумент fromfile_prefix_chars конструктора ArgumentParser), считываются по одному аргументу на строку. Метод convert_arg_line_to_args() можно переопределить для более сложного чтения.
Этот метод принимает один аргумент arg_line – строку, прочитанную из файла аргументов. Он возвращает список аргументов, разобранных из этой строки. Метод вызывается по одному разу для каждой строки из файла аргументов, по порядку.
Полезный вариант переопределения этого метода – такой, который воспринимает каждое слово, разделённое пробелом, как отдельный аргумент.
def convert_arg_line_to_args(self, arg_line): for arg in arg_line.split(): if not arg.strip(): continue yield arg
16.4.5.9. Методы выхода¶Exiting methods
- ArgumentParser.exit(status=0, message=None)¶
Этот метод завершает программу, выходя с указанным статус и, если задан, выводит сообщение перед этим.
- ArgumentParser.error(message)¶
Этот метод выводит сообщение об использовании, включая message, в стандартный поток ошибок и завершает программу с кодом возврата 2.
16.4.6. Обновление кода optparse¶Upgrading optparse code
Originally, the argparse module had attempted to maintain compatibility with optparse. However, optparse was difficult to extend transparently, particularly with the changes required to support the new nargs= specifiers and better usage messages. When most everything in optparse had either been copy-pasted over or monkey-patched, it no longer seemed practical to try to maintain the backwards compatibility.
Частичный путь обновления с 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.
- Замените аргумент version конструктора OptionParser на вызов parser.add_argument('--version', action='version', version='<the version>')