Рубрики
Без рубрики

argparse – параметр командной строки и анализ аргумента

Автор оригинала: Doug Hellmann.

Цель:

Разбор параметров и аргументов командной строки.

Модуль argparse включает инструменты для создания процессоров аргументов и опций командной строки. Он был добавлен в Python 2.7 вместо optparse . Реализация argparse поддерживает функции, которые было бы нелегко добавить в optparse , и для которых потребовались бы обратно несовместимые изменения API, поэтому в библиотека вместо этого. optparse больше не поддерживается.

Настройка парсера

Первым шагом при использовании argparse является создание объекта анализатора и указание ему ожидаемых аргументов. Затем анализатор можно использовать для обработки аргументов командной строки при запуске программы. Конструктор класса анализатора ( ArgumentParser ) принимает несколько аргументов для настройки описания, используемого в тексте справки для программы и других глобальных поведений или настроек.

import argparse
parser  argparse.ArgumentParser(
    description'This is a PyMOTW sample program',
)

Определение аргументов

argparse – это полная библиотека обработки аргументов. Аргументы могут запускать различные действия, указанные в аргументе action для add_argument () . Поддерживаемые действия включают сохранение аргумента (по отдельности или как часть списка), сохранение постоянного значения при обнаружении аргумента (включая специальную обработку значений true/false для логических переключателей), подсчет количества раз, когда аргумент встречается, и вызов обратного вызова для использования пользовательских инструкций обработки.

Действие по умолчанию – сохранить значение аргумента. Если тип указан, значение преобразуется в этот тип перед сохранением. Если указан аргумент dest , значение сохраняется с этим именем при анализе аргументов командной строки.

Анализ командной строки

После определения всех аргументов проанализируйте командную строку, передав последовательность строк аргументов в parse_args () . По умолчанию аргументы берутся из sys.argv [1:] , но можно использовать любой список строк. Параметры обрабатываются с использованием синтаксиса GNU/POSIX, поэтому значения параметров и аргументов могут быть смешаны в последовательности.

Возвращаемое значение из parse_args () – это пространство имен , содержащее аргументы команды. Объект содержит значения аргументов как атрибуты, поэтому, если для dest аргумента установлено значение "myoption" , значение доступно как args.myoption .

Простые примеры

Вот простой пример с тремя различными вариантами: логический параметр ( -a ), простой строковый параметр ( -b ) и целочисленный параметр ( - в ).

argparse_short.py

import argparse

parser  argparse.ArgumentParser(description'Short sample app')

parser.add_argument('-a', action"store_true", defaultFalse)
parser.add_argument('-b', action"store", dest"b")
parser.add_argument('-c', action"store", dest"c", typeint)

print(parser.parse_args(['-a', '-bval', '-c', '3']))

Есть несколько способов передать значения односимвольным параметрам. В предыдущем примере используются две разные формы: -bval и -c val .

$ python3 argparse_short.py
,

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

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

argparse_long.py

import argparse

parser  argparse.ArgumentParser(
    description'Example with long option names',
)

parser.add_argument('--noarg', action"store_true",
                    defaultFalse)
parser.add_argument('--witharg', action"store",
                    dest"witharg")
parser.add_argument('--witharg2', action"store",
                    dest"witharg2", typeint)

print(
    parser.parse_args(
        ['--noarg', '--witharg', 'val', '--witharg2=3']
    )
)

Результаты похожи.

$ python3 argparse_long.py
,

argparse – это полноценный инструмент синтаксического анализа аргументов командной строки, обрабатывающий как необязательные, так и обязательные аргументы.

argparse_arguments.py

import argparse

parser  argparse.ArgumentParser(
    description'Example with nonoptional arguments',
)

parser.add_argument('count', action"store", typeint)
parser.add_argument('units', action"store")

print(parser.parse_args())

В этом примере аргумент «count» является целым числом, а аргумент «units» сохраняется в виде строки. Если какое-либо из них не указано в командной строке или заданное значение не может быть преобразовано в правильный тип, выдается сообщение об ошибке.

$ python3 argparse_arguments.py 3 inches
)

$ python3 argparse_arguments.py some inches

usage: argparse_arguments.py [-h] count units
argparse_arguments.py: error: argument count: invalid int value:
'some'

$ python3 argparse_arguments.py

usage: argparse_arguments.py [-h] count units
argparse_arguments.py: error: the following arguments are
required: count, units

Аргумент Действия

При обнаружении аргумента может быть запущено любое из шести встроенных действий.

хранить

Сохраните значение, при необходимости преобразовав его в другой тип. Это действие по умолчанию, выполняемое, если ничего не указано явно.

store_const

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

store_true

/

store_false

Сохраните соответствующее логическое значение. Эти действия используются для реализовать логические переключатели.

добавить

Сохраните значение в списке. Если аргумент повторяется.

append_const

Сохраните значение, определенное в спецификации аргумента, в список.

версия

Распечатывает сведения о версии программы и закрывается.

Этот пример программы демонстрирует каждый тип действия с минимальной конфигурацией, необходимой для работы каждого из них.

argparse_action.py

import argparse

parser  argparse.ArgumentParser()

parser.add_argument('-s', action'store',
                    dest'simple_value',
                    help'Store a simple value')

parser.add_argument('-c', action'store_const',
                    dest'constant_value',
                    const'value-to-store',
                    help'Store a constant value')

parser.add_argument('-t', action'store_true',
                    defaultFalse,
                    dest'boolean_t',
                    help'Set a switch to true')
parser.add_argument('-f', action'store_false',
                    defaultTrue,
                    dest'boolean_f',
                    help'Set a switch to false')

parser.add_argument('-a', action'append',
                    dest'collection',
                    default[],
                    help'Add repeated values to a list')

parser.add_argument('-A', action'append_const',
                    dest'const_collection',
                    const'value-1-to-append',
                    default[],
                    help'Add different values to list')
parser.add_argument('-B', action'append_const',
                    dest'const_collection',
                    const'value-2-to-append',
                    help'Add different values to list')

parser.add_argument('--version', action'version',
                    version'%(prog)s 1.0')

results  parser.parse_args()
print('simple_value     = {!r}'.format(results.simple_value))
print('constant_value   = {!r}'.format(results.constant_value))
print('boolean_t        = {!r}'.format(results.boolean_t))
print('boolean_f        = {!r}'.format(results.boolean_f))
print('collection       = {!r}'.format(results.collection))
print('const_collection = {!r}'.format(results.const_collection))

Параметры -t и -f настроены для изменения различных значений параметров, каждое из которых хранит либо True, либо False. Значения dest для -A и -B одинаковы, поэтому их постоянные значения добавляются в один и тот же список.

$ python3 argparse_action.py -h

usage: argparse_action.py [-h] [-s SIMPLE_VALUE] [-c] [-t] [-f]
                          [-a COLLECTION] [-A] [-B] [--version]

optional arguments:
  -h, --help       show this help message and exit
  -s SIMPLE_VALUE  Store a simple value
  -c               Store a constant value
  -t               Set a switch to true
  -f               Set a switch to false
  -a COLLECTION    Add repeated values to a list
  -A               Add different values to list
  -B               Add different values to list
  --version        show program's version number and exit

$ python3 argparse_action.py -s value

simple_value     = 'value'
constant_value   = None
boolean_t        = False
boolean_f        = True
collection       = []
const_collection = []

$ python3 argparse_action.py -c

simple_value     = None
constant_value   = 'value-to-store'
boolean_t        = False
boolean_f        = True
collection       = []
const_collection = []

$ python3 argparse_action.py -t

simple_value     = None
constant_value   = None
boolean_t        = True
boolean_f        = True
collection       = []
const_collection = []

$ python3 argparse_action.py -f

simple_value     = None
constant_value   = None
boolean_t        = False
boolean_f        = False
collection       = []
const_collection = []

$ python3 argparse_action.py -a one -a two -a three

simple_value     = None
constant_value   = None
boolean_t        = False
boolean_f        = True
collection       = ['one', 'two', 'three']
const_collection = []

$ python3 argparse_action.py -B -A

simple_value     = None
constant_value   = None
boolean_t        = False
boolean_f        = True
collection       = []
const_collection = ['value-2-to-append', 'value-1-to-append']

$ python3 argparse_action.py --version

argparse_action.py 1.0

Префиксы опций

Синтаксис по умолчанию для параметров основан на соглашении Unix об обозначении переключателей командной строки с помощью префикса тире (“ - “). argparse поддерживает другие префиксы, поэтому программа может соответствовать локальной платформе по умолчанию (т. е. использовать «/» в Windows) или следовать другому соглашению.

argparse_prefix_chars.py

import argparse

parser  argparse.ArgumentParser(
    description'Change the option prefix characters',
    prefix_chars'-+/',
)

parser.add_argument('-a', action"store_false",
                    defaultNone,
                    help'Turn A off',
                    )
parser.add_argument('+a', action"store_true",
                    defaultNone,
                    help'Turn A on',
                    )
parser.add_argument('//noarg', '++noarg',
                    action"store_true",
                    defaultFalse)

print(parser.parse_args())

Задайте для параметра prefix_chars для ArgumentParser строку, содержащую все символы, которым должно быть разрешено обозначать параметры. Важно понимать, что хотя prefix_chars устанавливает разрешенные символы переключателя, определения отдельных аргументов определяют синтаксис для данного переключателя. Это дает явный контроль над тем, являются ли параметры, использующие разные префиксы, псевдонимами (например, в случае независимого от платформы синтаксиса командной строки) или альтернативными вариантами (например, использование “ + ” для указания включения переключателя и « - », чтобы выключить его). В предыдущем примере + a и -a являются отдельными аргументами, а //noarg также может быть задан как ++ noarg , но не --noarg .

$ python3 argparse_prefix_chars.py -h

usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg]

Change the option prefix characters

optional arguments:
  -h, --help        show this help message and exit
  -a                Turn A off
  +a                Turn A on
  //noarg, ++noarg

$ python3 argparse_prefix_chars.py +a


$ python3 argparse_prefix_chars.py -a


$ python3 argparse_prefix_chars.py //noarg


$ python3 argparse_prefix_chars.py ++noarg


$ python3 argparse_prefix_chars.py --noarg

usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg]
argparse_prefix_chars.py: error: unrecognized arguments: --noarg

Источники аргументов

До сих пор в примерах список аргументов, переданных синтаксическому анализатору, был получен из списка, переданного явно, или взяты неявно из sys.argv . Явная передача списка полезна при использовании argparse для обработки инструкций, подобных командной строке, которые не поступают из командной строки (например, в

argparse_with_shlex.py

import argparse
from configparser import ConfigParser
import shlex

parser  argparse.ArgumentParser(description'Short sample app')

parser.add_argument('-a', action"store_true", defaultFalse)
parser.add_argument('-b', action"store", dest"b")
parser.add_argument('-c', action"store", dest"c", typeint)

config  ConfigParser()
config.read('argparse_with_shlex.ini')
config_value  config.get('cli', 'options')
print('Config  :', config_value)

argument_list  shlex.split(config_value)
print('Arg List:', argument_list)

print('Results :', parser.parse_args(argument_list))

В этом примере используется configparser для чтения файла конфигурации.

[cli]
options  -a -b 2

shlex позволяет легко разделить строку, хранящуюся в файле конфигурации.

$ python3 argparse_with_shlex.py

Config  : -a -b 2
Arg List: ['-a', '-b', '2']
Results :,

Альтернативой обработке файла конфигурации в коде приложения является указание argparse , как распознать аргумент, который указывает входной файл, содержащий набор аргументов для обработки, используя fromfile_prefix_chars .

argparse_fromfile_prefix_chars.py

import argparse
import shlex

parser  argparse.ArgumentParser(description'Short sample app',
                                 fromfile_prefix_chars'@',
                                 )

parser.add_argument('-a', action"store_true", defaultFalse)
parser.add_argument('-b', action"store", dest"b")
parser.add_argument('-c', action"store", dest"c", typeint)

print(parser.parse_args(['@argparse_fromfile_prefix_chars.txt']))

В этом примере останавливается, когда он находит аргумент с префиксом @ , затем читается указанный файл, чтобы найти дополнительные аргументы. Файл должен содержать один

argparse_fromfile_prefix_chars.txt

-a
-b
2

Далее следует вывод, полученный при обработке argparse_from_prefix_chars.txt .

$ python3 argparse_fromfile_prefix_chars.py
,

Вывод справки

Автоматически созданная справка

argparse автоматически добавит параметры для создания справки, если это настроено. Аргумент add_help для ArgumentParser управляет параметрами, связанными со справкой.

argparse_with_help.py

import argparse

parser  argparse.ArgumentParser(add_helpTrue)

parser.add_argument('-a', action"store_true", defaultFalse)
parser.add_argument('-b', action"store", dest"b")
parser.add_argument('-c', action"store", dest"c", typeint)

print(parser.parse_args())

Параметры справки ( -h и --help ) добавляются по умолчанию, но их можно отключить, установив для add_help значение false.

argparse_without_help.py

import argparse

parser  argparse.ArgumentParser(add_helpFalse)

parser.add_argument('-a', action"store_true", defaultFalse)
parser.add_argument('-b', action"store", dest"b")
parser.add_argument('-c', action"store", dest"c", typeint)

print(parser.parse_args())

Хотя -h и --help по сути являются стандартными именами параметров для запроса справки, некоторым приложениям или использованию argparse справка не требуется. или необходимо использовать эти имена параметров для других целей.

$ python3 argparse_with_help.py -h

usage: argparse_with_help.py [-h] [-a] [-b B] [-c C]

optional arguments:
  -h, --help  show this help message and exit
  -a
  -b B
  -c C

$ python3 argparse_without_help.py -h

usage: argparse_without_help.py [-a] [-b B] [-c C]
argparse_without_help.py: error: unrecognized arguments: -h

Настройка справки

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

argparse_custom_help.py

import argparse

parser  argparse.ArgumentParser(add_helpTrue)

parser.add_argument('-a', action"store_true", defaultFalse)
parser.add_argument('-b', action"store", dest"b")
parser.add_argument('-c', action"store", dest"c", typeint)

print('print_usage output:')
parser.print_usage()
print()

print('print_help output:')
parser.print_help()

print_usage () печатает краткое сообщение об использовании для парсера аргументов, а print_help () печатает

$ python3 argparse_custom_help.py

print_usage output:
usage: argparse_custom_help.py [-h] [-a] [-b B] [-c C]

print_help output:
usage: argparse_custom_help.py [-h] [-a] [-b B] [-c C]

optional arguments:
  -h, --help  show this help message and exit
  -a
  -b B
  -c C

ArgumentParser использует класс средства форматирования для управления внешним видом справки.

Например, RawDescriptionHelpFormatter обходит перенос строк, обеспечиваемый средством форматирования по умолчанию.

argparse_raw_description_help_formatter.py

import argparse

parser  argparse.ArgumentParser(
    add_helpTrue,
    formatter_classargparse.RawDescriptionHelpFormatter,
    description"""
    description
        not
           wrapped""",
    epilog"""
    epilog
      not
         wrapped""",
)

parser.add_argument(
    '-a', action"store_true",
    help"""argument
    help is
    wrapped
    """,
)

parser.print_help()

Весь текст в описании и эпилоге команды останется.

$ python3 argparse_raw_description_help_formatter.py

usage: argparse_raw_description_help_formatter.py [-h] [-a]

    description
        not
           wrapped

optional arguments:
  -h, --help  show this help message and exit
  -a          argument help is wrapped

    epilog
      not
         wrapped

RawTextHelpFormatter обрабатывает весь текст справки как предварительно отформатированный.

argparse_raw_text_help_formatter.py

import argparse

parser  argparse.ArgumentParser(
    add_helpTrue,
    formatter_classargparse.RawTextHelpFormatter,
    description"""
    description
        not
           wrapped""",
    epilog"""
    epilog
      not
         wrapped""",
)

parser.add_argument(
    '-a', action"store_true",
    help"""argument
    help is not
    wrapped
    """,
)

parser.print_help()

Текст справки для аргумента -a больше не оформлен аккуратно.

$ python3 argparse_raw_text_help_formatter.py

usage: argparse_raw_text_help_formatter.py [-h] [-a]

    description
        not
           wrapped

optional arguments:
  -h, --help  show this help message and exit
  -a          argument
                  help is not
                  wrapped


    epilog
      not
         wrapped

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

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

argparse_metavar_type_help_formatter.py

import argparse

parser  argparse.ArgumentParser(
    add_helpTrue,
    formatter_classargparse.MetavarTypeHelpFormatter,
)

parser.add_argument('-i', typeint, dest'notshown1')
parser.add_argument('-f', typefloat, dest'notshown2')

parser.print_help()

Вместо отображения значения dest имя связанного типа

$ python3 argparse_metavar_type_help_formatter.py

usage: argparse_metavar_type_help_formatter.py [-h] [-i int] [-f
 float]

optional arguments:
  -h, --help  show this help message and exit
  -i int
  -f float

Организация парсера

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

Совместное использование правил парсера

Программистам обычно требуется реализовать набор инструментов командной строки, которые принимают набор аргументов и затем каким-то образом специализируются. Например, если все программы должны аутентифицировать пользователя перед тем, как предпринимать какие-либо реальные действия, все они должны поддерживать параметры --user и --password . Вместо того, чтобы явно добавлять параметры к каждому ArgumentParser , можно определить

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

argparse_parent_base.py

import argparse

parser  argparse.ArgumentParser(add_helpFalse)

parser.add_argument('--user', action"store")
parser.add_argument('--password', action"store")

Затем создайте еще один синтаксический анализатор с установленным parent :

argparse_uses_parent.py

import argparse
import argparse_parent_base

parser  argparse.ArgumentParser(
    parents[argparse_parent_base.parser],
)

parser.add_argument('--local-arg',
                    action"store_true",
                    defaultFalse)

print(parser.parse_args())

И получившаяся программа принимает все три варианта:

$ python3 argparse_uses_parent.py -h

usage: argparse_uses_parent.py [-h] [--user USER]
                               [--password PASSWORD]
                               [--local-arg]

optional arguments:
  -h, --help           show this help message and exit
  --user USER
  --password PASSWORD
  --local-arg

Конфликтующие варианты

В предыдущем примере было указано, что добавление двух обработчиков аргументов к синтаксическому анализатору с использованием одного и того же имени аргумента вызывает исключение. Поведение при разрешении конфликтов можно изменить, передав конфликт_обработчик . Двумя встроенными обработчиками являются error (по умолчанию) и resolve , который выбирает обработчик в зависимости от порядка

argparse_conflict_handler_resolve.py

import argparse

parser  argparse.ArgumentParser(conflict_handler'resolve')

parser.add_argument('-a', action"store")
parser.add_argument('-b', action"store", help'Short alone')
parser.add_argument('--long-b', '-b',
                    action"store",
                    help'Long and short together')

print(parser.parse_args(['-h']))

Поскольку используется последний обработчик с заданным именем аргумента, в этом примере автономный параметр -b замаскирован псевдонимом для --long-b .

$ python3 argparse_conflict_handler_resolve.py

usage: argparse_conflict_handler_resolve.py [-h] [-a A]
[--long-b LONG_B]

optional arguments:
  -h, --help            show this help message and exit
  -a A
  --long-b LONG_B, -b LONG_B
                        Long and short together

Изменение порядка вызовов на add_argument () демаскирует автономный параметр:

argparse_conflict_handler_resolve2.py

import argparse

parser  argparse.ArgumentParser(conflict_handler'resolve')

parser.add_argument('-a', action"store")
parser.add_argument('--long-b', '-b',
                    action"store",
                    help'Long and short together')
parser.add_argument('-b', action"store", help'Short alone')

print(parser.parse_args(['-h']))

Теперь оба варианта можно использовать вместе.

$ python3 argparse_conflict_handler_resolve2.py

usage: argparse_conflict_handler_resolve2.py [-h] [-a A]
                                             [--long-b LONG_B]
                                             [-b B]

optional arguments:
  -h, --help       show this help message and exit
  -a A
  --long-b LONG_B  Long and short together
  -b B             Short alone

Группы аргументов

argparse объединяет определения аргументов в «группы». По умолчанию он использует два

argparse_default_grouping.py

import argparse

parser  argparse.ArgumentParser(description'Short sample app')

parser.add_argument('--optional', action"store_true",
                    defaultFalse)
parser.add_argument('positional', action"store")

print(parser.parse_args())

Группировка отражается в отдельных разделах вывода справки «позиционные аргументы» и «необязательные аргументы».

$ python3 argparse_default_grouping.py -h

usage: argparse_default_grouping.py [-h] [--optional] positional

Short sample app

positional arguments:
  positional

optional arguments:
  -h, --help  show this help message and exit
  --optional

Группировку можно настроить, чтобы сделать ее более логичной в справке, чтобы связанные параметры или значения документировались вместе. Приведенный ранее пример с общими параметрами можно было бы написать с использованием настраиваемой группировки, чтобы параметры аутентификации

Создайте группу «аутентификации» с помощью add_argument_group () , а затем добавьте в группу каждый из параметров, связанных с аутентификацией, вместо базового анализатора.

argparse_parent_with_group.py

import argparse

parser  argparse.ArgumentParser(add_helpFalse)

group  parser.add_argument_group('authentication')

group.add_argument('--user', action"store")
group.add_argument('--password', action"store")

Программа, использующая родительский элемент на основе группы, перечисляет его в значении parent , просто

argparse_uses_parent_with_group.py

import argparse
import argparse_parent_with_group

parser  argparse.ArgumentParser(
    parents[argparse_parent_with_group.parser],
)

parser.add_argument('--local-arg',
                    action"store_true",
                    defaultFalse)

print(parser.parse_args())

В выводе справки теперь показаны параметры аутентификации вместе.

$ python3 argparse_uses_parent_with_group.py -h

usage: argparse_uses_parent_with_group.py [-h] [--user USER]
                                          [--password PASSWORD]
                                          [--local-arg]

optional arguments:
  -h, --help           show this help message and exit
  --local-arg

authentication:
  --user USER
  --password PASSWORD

Взаимоисключающие варианты

Определение взаимоисключающих параметров является частным случаем функции группировки параметров и использует add_mutually_exclusive_group () вместо add_argument_group () .

argparse_mutually_exclusive.py

import argparse

parser  argparse.ArgumentParser()

group  parser.add_mutually_exclusive_group()
group.add_argument('-a', action'store_true')
group.add_argument('-b', action'store_true')

print(parser.parse_args())

argparse обеспечивает взаимную исключительность, так что только один из вариантов из

$ python3 argparse_mutually_exclusive.py -h

usage: argparse_mutually_exclusive.py [-h] [-a | -b]

optional arguments:
  -h, --help  show this help message and exit
  -a
  -b

$ python3 argparse_mutually_exclusive.py -a


$ python3 argparse_mutually_exclusive.py -b


$ python3 argparse_mutually_exclusive.py -a -b

usage: argparse_mutually_exclusive.py [-h] [-a | -b]
argparse_mutually_exclusive.py: error: argument -b: not allowed
with argument -a

Вложенные парсеры

Подход родительского парсера, описанный ранее, является одним из способов обмена параметрами между связанными командами. Альтернативный подход – объединить команды в одну программу и использовать суб-парсеры для обработки каждой части командной строки. Результат работает так же, как svn , hg и другие программы с несколькими действиями или подкомандами командной строки.

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

argparse_subparsers.py

import argparse

parser  argparse.ArgumentParser()

subparsers  parser.add_subparsers(help'commands')

# A list command
list_parser  subparsers.add_parser(
    'list', help'List contents')
list_parser.add_argument(
    'dirname', action'store',
    help'Directory to list')

# A create command
create_parser  subparsers.add_parser(
    'create', help'Create a directory')
create_parser.add_argument(
    'dirname', action'store',
    help'New directory to create')
create_parser.add_argument(
    '--read-only', defaultFalse, action'store_true',
    help'Set permissions to prevent writing to the directory',
)

# A delete command
delete_parser  subparsers.add_parser(
    'delete', help'Remove a directory')
delete_parser.add_argument(
    'dirname', action'store', help'The directory to remove')
delete_parser.add_argument(
    '--recursive', '-r', defaultFalse, action'store_true',
    help'Remove the contents of the directory, too',
)

print(parser.parse_args())

Вывод справки показывает названные суб-парсеры как “команды”, которые можно указать

$ python3 argparse_subparsers.py -h

usage: argparse_subparsers.py [-h] {list,create,delete} ...

positional arguments:
  {list,create,delete}  commands
    list                List contents
    create              Create a directory
    delete              Remove a directory

optional arguments:
  -h, --help            show this help message and exit

У каждого суб-парсера также есть собственная справка, описывающая аргументы и параметры для

$ python3 argparse_subparsers.py create -h

usage: argparse_subparsers.py create [-h] [--read-only] dirname

positional arguments:
  dirname      New directory to create

optional arguments:
  -h, --help   show this help message and exit
  --read-only  Set permissions to prevent writing to the directo
ry

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

$ python3 argparse_subparsers.py delete -r foo
,

Расширенная обработка аргументов

В примерах до сих пор были показаны простые логические флаги, параметры со строкой или

Списки переменных аргументов

Определение одного аргумента может быть настроено на использование нескольких аргументов в анализируемой командной строке. Установите для nargs одно из значений флага из таблицы ниже в зависимости от количества требуемых или ожидаемых аргументов.

Флаги для определений переменных аргументов в argparse

Ценить

Смысл

Абсолютное количество аргументов (например,

).

0 или 1 аргумент

0 или все аргументы

Все и хотя бы один аргумент

argparse_nargs.py

import argparse

parser  argparse.ArgumentParser()

parser.add_argument('--three', nargs3)
parser.add_argument('--optional', nargs'?')
parser.add_argument('--all', nargs'*', dest'all')
parser.add_argument('--one-or-more', nargs'+')

print(parser.parse_args())

Синтаксический анализатор применяет инструкции по подсчету аргументов и генерирует точную синтаксическую диаграмму как часть текста справки по команде.

$ python3 argparse_nargs.py -h

usage: argparse_nargs.py [-h] [--three THREE THREE THREE]
                [--optional [OPTIONAL]]
                [--all [ALL [ALL ...]]]
                [--one-or-more ONE_OR_MORE [ONE_OR_MORE ...]]

optional arguments:
  -h, --help            show this help message and exit
  --three THREE THREE THREE
  --optional [OPTIONAL]
  --all [ALL [ALL ...]]
  --one-or-more ONE_OR_MORE [ONE_OR_MORE ...]

$ python3 argparse_nargs.py


$ python3 argparse_nargs.py --three

usage: argparse_nargs.py [-h] [--three THREE THREE THREE]
                [--optional [OPTIONAL]]
                [--all [ALL [ALL ...]]]
                [--one-or-more ONE_OR_MORE [ONE_OR_MORE ...]]
argparse_nargs.py: error: argument --three: expected 3
argument(s)

$ python3 argparse_nargs.py --three a b c

three=['a', 'b', 'c'])

$ python3 argparse_nargs.py --optional


$ python3 argparse_nargs.py --optional with_value
,

$ python3 argparse_nargs.py --all with multiple values

Namespace(all=['with', 'multiple', 'values'],

$ python3 argparse_nargs.py --one-or-more with_value
 one_or_more=['with_value'],

$ python3 argparse_nargs.py --one-or-more with multiple values
 one_or_more=['with', 'multiple', 'values'],

$ python3 argparse_nargs.py --one-or-more

usage: argparse_nargs.py [-h] [--three THREE THREE THREE]
                [--optional [OPTIONAL]]
                [--all [ALL [ALL ...]]]
                [--one-or-more ONE_OR_MORE [ONE_OR_MORE ...]]
argparse_nargs.py: error: argument --one-or-more: expected
at least one argument

Типы аргументов

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

argparse_type.py

import argparse

parser  argparse.ArgumentParser()

parser.add_argument('-i', typeint)
parser.add_argument('-f', typefloat)
parser.add_argument('--file', typeopen)

try:
    print(parser.parse_args())
except IOError as msg:
    parser.error(str(msg))

Любой вызываемый объект, который принимает единственный строковый аргумент, может быть передан как type , включая встроенные типы, такие как int и float , или даже open () .

$ python3 argparse_type.py -i 1


$ python3 argparse_type.py -f 3.14


$ python3 argparse_type.py --file argparse_type.py
>,

Если преобразование типа не удается, argparse вызывает исключение. Исключения TypeError и ValueError перехватываются автоматически и преобразуются в простое сообщение об ошибке для пользователя. Другие исключения, такие как IOError в следующем примере, где вход

$ python3 argparse_type.py -i a

usage: argparse_type.py [-h] [-i I] [-f F] [--file FILE]
argparse_type.py: error: argument -i: invalid int value: 'a'

$ python3 argparse_type.py -f 3.14.15

usage: argparse_type.py [-h] [-i I] [-f F] [--file FILE]
argparse_type.py: error: argument -f: invalid float value:
'3.14.15'

$ python3 argparse_type.py --file does_not_exist.txt

usage: argparse_type.py [-h] [-i I] [-f F] [--file FILE]
argparse_type.py: error: [Errno 2] No such file or directory:
'does_not_exist.txt'

Чтобы ограничить входной аргумент значением в пределах заранее определенного набора, используйте параметр choices .

argparse_choices.py

import argparse

parser  argparse.ArgumentParser()

parser.add_argument(
    '--mode',
    choices('read-only', 'read-write'),
)

print(parser.parse_args())

Если аргумент --mode не является одним из допустимых значений, генерируется ошибка и обработка останавливается.

$ python3 argparse_choices.py -h

usage: argparse_choices.py [-h] [--mode {read-only,read-write}]

optional arguments:
  -h, --help            show this help message and exit
  --mode {read-only,read-write}

$ python3 argparse_choices.py --mode read-only
)

$ python3 argparse_choices.py --mode invalid

usage: argparse_choices.py [-h] [--mode {read-only,read-write}]
argparse_choices.py: error: argument --mode: invalid choice:
'invalid' (choose from 'read-only', 'read-write')

Аргументы файла

Хотя объекты file могут быть созданы с помощью одного строкового аргумента, он не включает аргумент режима доступа. FileType предоставляет более гибкий способ указать, что аргумент должен быть файлом, включая режим и буфер.

argparse_FileType.py

import argparse

parser  argparse.ArgumentParser()

parser.add_argument('-i', metavar'in-file',
                    typeargparse.FileType('rt'))
parser.add_argument('-o', metavar'out-file',
                    typeargparse.FileType('wt'))

try:
    results  parser.parse_args()
    print('Input file:', results.i)
    print('Output file:', results.o)
except IOError as msg:
    parser.error(str(msg))

Значение, связанное с именем аргумента, – это дескриптор открытого файла. Приложение отвечает за закрытие файла, когда он больше не

$ python3 argparse_FileType.py -h

usage: argparse_FileType.py [-h] [-i in-file] [-o out-file]

optional arguments:
  -h, --help   show this help message and exit
  -i in-file
  -o out-file

$ python3 argparse_FileType.py -i argparse_FileType.py -o tmp_\
file.txt

Input file: <_io.TextIOWrapper>
Output file: <_io.TextIOWrapper>

$ python3 argparse_FileType.py -i no_such_file.txt

usage: argparse_FileType.py [-h] [-i in-file] [-o out-file]
argparse_FileType.py: error: argument -i: can't open
'no_such_file.txt': [Errno 2] No such file or directory:
'no_such_file.txt'

Настраиваемые действия

В дополнение к встроенным действиям, описанным ранее, пользовательские действия могут быть определены путем предоставления объекта, реализующего Action API. Объект, переданный в add_argument () как action , должен принимать параметры, описывающие определяемый аргумент (все те же аргументы, что и add_argument () ) и вернуть вызываемый объект, который принимает в качестве параметров parser , обрабатывающий аргументы, namespace , содержащий результаты синтаксического анализа, значение аргумента, с которым действуют , и option_string , которая запустила

Класс Action предоставляется как удобная отправная точка для определения новых

argparse_custom_action.py

import argparse


class CustomAction(argparse.Action):
    def __init__(self,
                 option_strings,
                 dest,
                 nargsNone,
                 constNone,
                 defaultNone,
                 typeNone,
                 choicesNone,
                 requiredFalse,
                 helpNone,
                 metavarNone):
        argparse.Action.__init__(self,
                                 option_stringsoption_strings,
                                 destdest,
                                 nargsnargs,
                                 constconst,
                                 defaultdefault,
                                 typetype,
                                 choiceschoices,
                                 requiredrequired,
                                 helphelp,
                                 metavarmetavar,
                                 )
        print('Initializing CustomAction')
        for name, value in sorted(locals().items()):
            if name  'self' or value is None:
                continue
            print('  {} = {!r}'.format(name, value))
        print()
        return

    def __call__(self, parser, namespace, values,
                 option_stringNone):
        print('Processing CustomAction for {}'.format(self.dest))
        print('  parser = {}'.format(id(parser)))
        print('  values = {!r}'.format(values))
        print('  option_string = {!r}'.format(option_string))

        # Do some arbitrary processing of the input values
        if isinstance(values, list):
            values  [v.upper() for v in values]
        else:
            values  values.upper()
        # Save the results in the namespace using the destination
        # variable given to our constructor.
        setattr(namespace, self.dest, values)
        print()


parser  argparse.ArgumentParser()

parser.add_argument('-a', actionCustomAction)
parser.add_argument('-m', nargs'*', actionCustomAction)

results  parser.parse_args(['-a', 'value',
                             '-m', 'multivalue',
                             'second'])
print(results)

Тип значений зависит от значения nargs . Если аргумент допускает несколько значений, values будет списком, даже если он только

Значение option_string также зависит от исходной спецификации аргумента. За

$ python3 argparse_custom_action.py

Initializing CustomAction
  dest = 'a'
  option_strings = ['-a']
  required = False

Initializing CustomAction
  dest = 'm'
  nargs = '*'
  option_strings = ['-m']
  required = False

Processing CustomAction for a
  parser = 4315836992
  values = 'value'
  option_string = '-a'

Processing CustomAction for m
  parser = 4315836992
  values = ['multivalue', 'second']
  option_string = '-m'
, m=['MULTIVALUE', 'SECOND'])

Смотрите также