Документация Python неофициальный перевод
Содержание страницы

argparse – Парсер для параметров командной строки, аргументов и подкомандargparse – Parser for command-line options, arguments and sub-commands

Новое в версии 3.2.

Исходный код: Lib/argparse.py


Модуль argparse упрощает создание удобных интерфейсов командной строки. Программа определяет, какие аргументы ей нужны, а argparse сам решает, как извлечь их из sys.argv. Модуль argparse также автоматически формирует сообщения справки и подсказки по использованию и выводит ошибки, когда пользователь передаёт программе неверные аргументы.

Пример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

options:
 -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'

В следующих разделах этот пример разбирается подробно.

Создание парсераCreating a parser

Первый шаг при использовании argparse – создание объекта ArgumentParser:

>>> parser = argparse.ArgumentParser(description='Process some integers.')

Объект ArgumentParser будет содержать всю информацию, необходимую для разбора командной строки в типы данных Python.

Добавление аргументов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(), если нет.

Разбор аргументов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.

Объекты 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, allow_abbrev=True, exit_on_error=True)

Создаёт новый объект ArgumentParser. Все параметры должны передаваться как именованные аргументы. Каждый параметр имеет собственное подробное описание ниже, но вкратце они таковы:

  • prog – имя программы (по умолчанию: os.path.basename(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)

  • allow_abbrev – позволяет сокращать длинные параметры, если сокращение однозначно. (по умолчанию: True)

  • exit_on_error – определяет, завершает ли ArgumentParser работу с сообщением об ошибке при её возникновении. (по умолчанию: True)

Изменено в версии 3.5: allow_abbrev – добавлен параметр.

Изменено в версии 3.8: В предыдущих версиях allow_abbrev также отключал группировку коротких флагов, например -vv для обозначения -v -v.

Изменено в версии 3.9: exit_on_error – добавлен параметр.

В следующих разделах описывается, как используется каждый из этих параметров.

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]

options:
 -h, --help  show this help message and exit
 --foo FOO   foo help
$ cd ..
$ python subdir/myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

options:
 -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]

options:
 -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]

options:
 -h, --help  show this help message and exit
 --foo FOO   foo of the myprogram program

использование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

options:
 -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

options:
 -h, --help   show this help message and exit
 --foo [FOO]  foo help

Спецификатор формата %(prog)s используется для подстановки имени программы в сообщения об использовании.

описаниеdescription

В большинстве вызовов конструктора ArgumentParser используется именованный аргумент description=. Этот аргумент содержит краткое описание того, что делает программа и как она работает. В сообщениях справки это описание выводится между строкой использования командной строки и справкой по отдельным аргументам:

>>> parser = argparse.ArgumentParser(description='A foo that bars')
>>> parser.print_help()
usage: argparse.py [-h]

A foo that bars

options:
 -h, --help  show this help message and exit

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

эпилог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

options:
 -h, --help  show this help message and exit

And that's how you'd foo a bar

Как и для аргумента description, текст epilog= по умолчанию переносится по строкам, но это поведение можно настроить с помощью аргумента formatter_class для ArgumentParser.

родительские парсеры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=. Если изменить родительские парсеры после создания дочернего, эти изменения не отразятся на дочернем парсере.

класс форматирования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

options:
 -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

options:
 -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 ...]

positional arguments:
 bar         BAR! (default: [1, 2, 3])

options:
 -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

options:
  -h, --help  show this help message and exit
  --foo int

символы префикса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 будут запрещены.

символы префикса из файла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, что означает, что аргументы никогда не будут рассматриваться как ссылки на файлы.

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()

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.

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]

options:
 -h, --help  show this help message and exit
 -f FOO      old foo help
 --foo FOO   new foo help

Обратите внимание, что объекты ArgumentParser удаляют действие только в том случае, если все его строки опций переопределены. Поэтому в приведённом выше примере старое действие -f/--foo сохраняется как действие -f, поскольку была переопределена только строка опции --foo.

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]

options:
 -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]

options:
 --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]

options:
  +h, ++help  show this help message and exit

exit_on_error

Обычно при передаче недопустимого списка аргументов методу parse_args() объекта ArgumentParser происходит завершение с сообщением об ошибке.

Если требуется перехватывать ошибки вручную, эту возможность можно включить, установив exit_on_error в False:

>>> parser = argparse.ArgumentParser(exit_on_error=False)
>>> parser.add_argument('--integers', type=int)
_StoreAction(option_strings=['--integers'], dest='integers', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> try:
...     parser.parse_args('--integers a'.split())
... except argparse.ArgumentError:
...     print('Catching an argumentError')
...
Catching an argumentError

Новое в версии 3.9.

Метод add_argument()The add_argument() method

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

Определяет, как должен разбираться один аргумент командной строки. Каждый параметр подробно описан ниже, а кратко они таковы:

  • name or flags – имя или список строк параметров, например foo или -f, --foo.

  • action – базовый тип действия, которое выполняется при встрече этого аргумента в командной строке.

  • nargs – количество аргументов командной строки, которое должно быть потреблено.

  • const – постоянное значение, требуемое некоторыми значениями action и nargs.

  • default – значение, которое используется, если аргумент отсутствует в командной строке и в объекте namespace.

  • type – тип, в который следует преобразовать аргумент командной строки.

  • choices – последовательность допустимых значений для аргумента.

  • required – может ли параметр командной строки быть опущен (только для опциональных параметров).

  • help – краткое описание того, что делает аргумент.

  • metavar – имя аргумента в сообщениях об использовании.

  • dest – имя атрибута, добавляемого в объект, возвращаемый parse_args().

В следующих разделах описывается, как используется каждый из этих параметров.

имя или флаги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: the following arguments are required: bar

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. Действие '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', default=0)
    >>> parser.parse_args(['-vvv'])
    Namespace(verbose=3)
    

    Обратите внимание: значение default будет None, если только оно явно не установлено в 0.

  • '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
    
  • 'extend' – сохраняет список и добавляет каждое значение аргумента в этот список. Пример использования:

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument("--foo", action="extend", nargs="+", type=str)
    >>> parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"])
    Namespace(foo=['f1', 'f2', 'f3', 'f4'])
    

    Новое в версии 3.8.

Также можно задать произвольное действие, передав подкласс Action или другой объект, реализующий тот же интерфейс. BooleanOptionalAction доступен в argparse и добавляет поддержку булевых действий, таких как --foo и --no-foo:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action=argparse.BooleanOptionalAction)
>>> parser.parse_args(['--no-foo'])
Namespace(foo=False)

Новое в версии 3.9.

Рекомендуемый способ создания пользовательского действия – расширить Action, переопределив метод __call__ и, при необходимости, методы __init__ и format_usage.

Пример пользовательского действия:

>>> class FooAction(argparse.Action):
...     def __init__(self, option_strings, dest, nargs=None, **kwargs):
...         if nargs is not None:
...             raise ValueError("nargs not allowed")
...         super().__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.

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: the following arguments are required: foo
    

Если именованный аргумент nargs не указан, количество потребляемых аргументов определяется действием action. Обычно это означает, что будет потреблён один аргумент командной строки и создан один элемент (не список).

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.

default

Все необязательные аргументы и некоторые позиционные аргументы могут быть опущены в командной строке. Именованный аргумент 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 не перезапишет его:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args([], namespace=argparse.Namespace(foo=101))
Namespace(foo=101)

Если значение 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'])
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')

типtype

По умолчанию анализатор считывает аргументы командной строки как простые строки. Однако довольно часто строку командной строки следует интерпретировать как другой тип, например float или int. Именованный аргумент type функции add_argument() позволяет выполнять любые необходимые проверки и преобразования типов.

Если именованный аргумент type используется вместе с default, преобразователь типа применяется только в том случае, если значение по умолчанию является строкой.

Аргумент type может быть любым вызываемым объектом, принимающим одну строку. Если функция вызывает исключения ArgumentTypeError, TypeError или ValueError, оно перехватывается и отображается красиво отформатированное сообщение об ошибке. Другие типы исключений не обрабатываются.

Распространённые встроенные типы и функции можно использовать в качестве преобразователей типов:

import argparse
import pathlib

parser = argparse.ArgumentParser()
parser.add_argument('count', type=int)
parser.add_argument('distance', type=float)
parser.add_argument('street', type=ascii)
parser.add_argument('code_point', type=ord)
parser.add_argument('source_file', type=open)
parser.add_argument('dest_file', type=argparse.FileType('w', encoding='latin-1'))
parser.add_argument('datapath', type=pathlib.Path)

Пользовательские функции также можно использовать:

>>> def hyphenated(string):
...     return '-'.join([word[:4] for word in string.casefold().split()])
...
>>> parser = argparse.ArgumentParser()
>>> _ = parser.add_argument('short_title', type=hyphenated)
>>> parser.parse_args(['"The Tale of Two Cities"'])
Namespace(short_title='"the-tale-of-two-citi')

Функция bool() не рекомендуется в качестве преобразователя типов. Она лишь преобразует пустые строки в False, а непустые – в True. Обычно это не то, что нужно.

В целом, ключевое слово type – это удобство, которое следует использовать только для простых преобразований, способных вызывать лишь одно из трёх поддерживаемых исключений. Всё, что связано с более сложной обработкой ошибок или управлением ресурсами, должно выполняться ниже по потоку после разбора аргументов.

Например, преобразования JSON или YAML содержат сложные случаи ошибок, которые требуют более детального отчёта, чем может дать ключевое слово type. Сообщение JSONDecodeError не будет хорошо отформатировано, а исключение FileNotFound вообще не будет обработано.

Даже FileType имеет свои ограничения при использовании с ключевым словом type. Если один аргумент использует FileType, а затем следующий аргумент завершается ошибкой, сообщается об ошибке, но файл не закрывается автоматически. В этом случае лучше подождать, пока парсер завершит работу, а затем использовать оператор with для управления файлами.

Для проверок типов, которые просто сравнивают с фиксированным набором значений, рассмотрите вместо этого использование ключевого слова choices.

choices

Некоторые аргументы командной строки должны выбираться из ограниченного набора значений. Это можно обработать, передав объект-последовательность в качестве ключевого аргумента 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 проверяется после выполнения преобразований 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)

В качестве значения choices можно передать любую последовательность, поэтому поддерживаются объекты list, объекты tuple и пользовательские последовательности.

Использование enum.Enum не рекомендуется, поскольку сложно контролировать его отображение в сообщениях об использовании, справке и ошибках.

Форматированные варианты выбора переопределяют стандартное metavar, которое обычно берётся из dest. Обычно это то, что нужно, поскольку пользователь никогда не видит параметр dest. Если такое отображение нежелательно (возможно, потому что вариантов много), просто укажите явное metavar.

required

В целом, модуль argparse предполагает, что флаги вида -f и --bar обозначают необязательные аргументы, которые всегда можно опустить в командной строке. Чтобы сделать опцию обязательной, для ключевого аргумента required= функции add_argument() можно указать True:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: [-h] --foo FOO
: error: the following arguments are required: --foo

Как показано в примере, если опция помечена как required, parse_args() сообщит об ошибке, если эта опция отсутствует в командной строке.

Примечание

Обязательные опции обычно считаются дурным тоном, поскольку пользователи ожидают, что опции будут необязательными, поэтому их следует по возможности избегать.

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'])
usage: frobble [-h] [--foo] bar [bar ...]

positional arguments:
 bar     one of the bars to be frobbled

options:
 -h, --help  show this help message and exit
 --foo   foo the bars before frobbling

Строки help могут содержать различные спецификаторы формата, чтобы избежать повторения таких элементов, как имя программы или значение по умолчанию аргумента. Доступные спецификаторы включают имя программы, %(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)

options:
 -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]

options:
  -h, --help  show this help message and exit

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

options:
 -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

options:
 -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]

options:
 -h, --help     show this help message and exit
 -x X X
 --foo bar baz

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')

Классы действийAction classes

Классы действий реализуют API Action – вызываемый объект, который возвращает вызываемый объект, обрабатывающий аргументы командной строки. Любой объект, следующий этому 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.

Подклассы Action могут определять метод format_usage, который не принимает аргументов и возвращает строку, используемую при выводе справки об использовании программы. Если такой метод не предоставлен, будет использовано разумное значение по умолчанию.

Метод parse_args()The parse_args() method

ArgumentParser.parse_args(args=None, namespace=None)

Преобразует строки аргументов в объекты и назначает их в качестве атрибутов пространства имён. Возвращает заполненное пространство имён.

Предыдущие вызовы add_argument() определяют, какие объекты создаются и как они назначаются. Подробнее см. документацию add_argument().

  • args – список строк для разбора. По умолчанию берётся из sys.argv.

  • namespace – объект, в который будут помещены атрибуты. По умолчанию – новый пустой объект Namespace.

Синтаксис значений параметровOption value syntax

Метод 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')

Недопустимые аргументы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

Аргументы, содержащие -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)

Сокращения аргументов (совпадение по префиксу)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

Выдаётся ошибка для аргументов, которые могут соответствовать нескольким опциям. Эту возможность можно отключить, установив allow_abbrev в False.

За пределами sys.argvBeyond 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])

Объект NamespaceThe Namespace object

class argparse.Namespace

Простой класс, используемый по умолчанию в parse_args() для создания объекта, содержащего атрибуты, и его возврата.

Этот класс намеренно прост, всего лишь подкласс object с читаемым строковым представлением. Если нужно dict-подобное представление атрибутов, можно воспользоваться стандартной идиомой 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'

Другие утилитыOther utilities

ПодкомандыSub-commands

ArgumentParser.add_subparsers([title][, description][, prog][, parser_class][, action][, option_strings][, dest][, required][, 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)

  • action – базовый тип действия, которое будет выполнено при обнаружении этого аргумента в командной строке

  • dest – имя атрибута, в котором будет сохранено имя подкоманды; по умолчанию None, значение не сохраняется

  • required – указывает, обязательно ли должна быть указана подкоманда; по умолчанию False (добавлено в версии 3.7)

  • 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

options:
  -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

options:
  -h, --help  show this help message and exit

>>> parser.parse_args(['b', '--help'])
usage: PROG b [-h] [--baz {X,Y,Z}]

options:
  -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} ...

options:
  -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(required=True)
>>>
>>> # создать парсер для команды "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')

Изменено в версии 3.7: Новый required именованный аргумент.

Объекты FileTypeFileType objects

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.

Группы аргументов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

Обратите внимание, что любые аргументы, не входящие в ваши пользовательские группы, окажутся обратно в обычных разделах «позиционные аргументы» и «опциональные аргументы».

Взаимное исключение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().

Умолчания парсера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'

Вывод справки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.

Частичный разбор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(). Парсер может поглотить параметр, даже если он является всего лишь префиксом одного из известных параметров, вместо того чтобы оставить его в списке оставшихся аргументов.

Настройка разбора файловCustomizing file parsing

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()

Методы завершенияExiting methods

ArgumentParser.exit(status=0, message=None)

Этот метод завершает программу, выходя с указанным status и, если задано, перед этим выводит message. Пользователь может переопределить этот метод, чтобы обрабатывать эти шаги иначе:

class ErrorCatchingArgumentParser(argparse.ArgumentParser):
    def exit(self, status=0, message=None):
        if status:
            raise Exception(f'Exiting because of an error: {message}')
        exit(status)
ArgumentParser.error(message)

Этот метод выводит сообщение об использовании, включая message, в стандартный поток ошибок и завершает программу с кодом возврата 2.

Смешанный разборIntermixed parsing

ArgumentParser.parse_intermixed_args(args=None, namespace=None)
ArgumentParser.parse_known_intermixed_args(args=None, namespace=None)

Многие команды Unix позволяют пользователю смешивать опциональные аргументы с позиционными. Методы parse_intermixed_args() и parse_known_intermixed_args() поддерживают такой стиль разбора.

Эти парсеры не поддерживают все возможности argparse и вызывают исключения при использовании неподдерживаемых возможностей. В частности, подпарсеры, argparse.REMAINDER, и взаимоисключающие группы, включающие как опциональные, так и позиционные аргументы, не поддерживаются.

Следующий пример показывает разницу между parse_known_args() и parse_intermixed_args(): первый возвращает ['2', '3'] как неразобранные аргументы, в то время как второй собирает все позиционные аргументы в rest.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('cmd')
>>> parser.add_argument('rest', nargs='*', type=int)
>>> parser.parse_known_args('doit 1 --foo bar 2 3'.split())
(Namespace(cmd='doit', foo='bar', rest=[1]), ['2', '3'])
>>> parser.parse_intermixed_args('doit 1 --foo bar 2 3'.split())
Namespace(cmd='doit', foo='bar', rest=[1, 2, 3])

parse_known_intermixed_args() возвращает кортеж из двух элементов, содержащий заполненное пространство имён и список оставшихся строк аргументов. parse_intermixed_args() вызывает ошибку, если остаются какие-либо неразобранные строки аргументов.

Добавлено в версии 3.7.

Обновление кода optparseUpgrading optparse code

Изначально модуль argparse пытался сохранять совместимость с optparse. Однако optparse было сложно прозрачно расширять, особенно с изменениями, необходимыми для поддержки новых спецификаторов nargs= и более качественных сообщений об использовании. Когда почти всё в optparse было либо скопировано, либо пропатчено (monkey-patched), попытки поддерживать обратную совместимость перестали казаться практичными.

Модуль 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.

  • Замените optparse.OptionParser.disable_interspersed_args(), используя parse_intermixed_args() вместо parse_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>').