argparse: обязательный список параметров add_mutually_exclusive_group как необязательный?

Я знаю, что argparse описывает в своем документация о том, что параметры, начинающиеся с - или --, считаются необязательными:

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

Независимо от того, определяете ли вы параметры как обязательные или нет, они будут отображаться в разделе «необязательные аргументы» в выводе справки argparse:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--required_argument', action='store_true',  required=True)
parser.add_argument('--optional_argument', action='store_false', required=False)
parser.add_argument('positional_argument')
args = parser.parse_args()

Это приводит к следующему выводу справки:

usage: demo.py [-h] --required_argument [--optional_argument] positional_argument

positional arguments:
  positional_argument

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

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

Я уже знаю, что для этого есть обходной путь, используя add_argument_group() вот так:

import argparse

parser = argparse.ArgumentParser()
group1 = parser.add_argument_group(title='required arguments')
group1.add_argument('--required_argument', action='store_true',  required=True)
parser.add_argument('--optional_argument', action='store_false', required=False)
parser.add_argument('positional_argument')
args = parser.parse_args()
usage: demo.py [-h] --required_argument [--optional_argument] positional_argument

positional arguments:
  positional_argument

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

required arguments:
  --required_argument

Но как добиться подобного, если у вас есть взаимоисключающие аргументы? Предположим, вам нужно указать один из двух аргументов, но не оба одновременно. Я знаю, что есть лучшие варианты, как в этом примере, но ради этого: Когда вам нужно, чтобы пользователь использовал либо --enable, либо --disable: нужно указать один, но оба не имеют смысла.

Если это реализовано таким образом, я не знаю, как сделать так, чтобы он не попадал в «необязательные аргументы», поскольку add_mutually_exclusive_group() не поддерживает аргументы "заголовок" и "описание" add_argument_group():

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

import argparse

parser = argparse.ArgumentParser()
group1 = parser.add_mutually_exclusive_group(required=True)
group1.add_argument('--enable',  action='store_true',  help='Enable something')
group1.add_argument('--disable', action='store_false', help='Disable something')
args = parser.parse_args()
usage: demo.py [-h] (--enable | --disable)

optional arguments:
  -h, --help  show this help message and exit
  --enable    Enable something
  --disable   Disable something

Итак, кто-нибудь знает решение с argparse или это запрос на демонстрацию и один нужно переключиться на что-то другое, например click?


person Judge    schedule 16.01.2020    source источник
comment
Вы можете определить взаимоисключающую группу внутри группы аргументов. Обычно группы не предназначены для вложения, но эта конкретная комбинация работает и полезна.   -  person hpaulj    schedule 16.01.2020
comment
Есть две группы аргументов по умолчанию, одна помечена positional, а другая optional. Имена отражают историческое использование и то, как они обрабатываются (а не значение параметра required). Использование «параметров» или «необязательных параметров» восходит к unix getopt парсерам. Я предпочитаю термин flagged.   -  person hpaulj    schedule 16.01.2020


Ответы (1)


Обратите внимание на примечание к параметру required:

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

Поэтому не используйте обязательные параметры; вместо этого используйте позиционные аргументы с choices или вспомогательным парсером. Вот пример с позиционными выражениями, который, как вы заметите, намного проще:

import argparse

parser = argparse.ArgumentParser(prog='demo.py')
parser.add_argument('action', choices=['enable', 'disable'], help='Action to take')

parser.print_help()

for arg in ['enable', 'disable', 'rotate']:
    print()
    print(parser.parse_args([arg]))

Выход:

usage: demo.py [-h] {enable,disable}

positional arguments:
  {enable,disable}  Action to take

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

Namespace(action='enable')

Namespace(action='disable')

usage: demo.py [-h] {enable,disable}
demo.py: error: argument action: invalid choice: 'rotate' (choose from 'enable', 'disable')
person wjandrea    schedule 16.01.2020