argparse взаимное исключение между одним или двумя аргументами - PullRequest
0 голосов
/ 04 января 2019

Вот минимальный код для того, что я хочу сделать,

import argparse

parser = argparse.ArgumentParser( prog="test")

subparsers = parser.add_subparsers(title='sub-commands')
num  = subparsers.add_parser("num")
num.add_argument("-n")
numr = num.add_argument_group("Required arguments")

onr  =numr.add_mutually_exclusive_group(required=True)
onr.add_argument("-x")
onr2 = onr.add_argument_group("new")
onr2.add_argument("-y")
onr2.add_argument("-z")

Итак, я хочу, чтобы пользователь предоставил либо x, либо оба y, z, поэтому подумалдобавления взаимоисключающей группы из одного аргумента и одной группы.И это должно быть под подкомандой num.Этот код дает этот вывод

usage: test num [-h] [-n N] -x X [-y Y] [-z Z]

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

Required arguments:
  -x X

Нет информации о y, z, а также дает y, z не работает

python test.py num -y 9 -z 10
usage: test num [-h] [-n N] -x X [-y Y] [-z Z]
test num: error: one of the arguments -x is required

Как сделатьЯ достигаю этого, используя argparse, или это вообще возможно?

1 Ответ

0 голосов
/ 04 января 2019

Рекомендую удалить причудливое тестирование по x, y, z и выполнить его самостоятельно после разбора.Логика попытки сделать это в argparse сама по себе слишком сложна.Тестирование не так уж плохо, но хороший пользовательский интерфейс сложнее.

import argparse

parser = argparse.ArgumentParser( prog="test")

subparsers = parser.add_subparsers(title='sub-commands')
num  = subparsers.add_parser("num")
num.add_argument("-n")
numr = num.add_argument_group("Required arguments")

#onr  =numr.add_mutually_exclusive_group(required=True)
numr.add_argument("-x")
#onr2 = onr.add_argument_group("new")
numr.add_argument("-y")
numr.add_argument("-z")

args = parser.parse_args()
print(args)

if args.x is None:
    if args.y is None or args.z is None:
        parser.error('both y and z are required')

пример сеанса:

1122:~/mypy$ python3 stack54033455.py -h
usage: test [-h] {num} ...

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

sub-commands:
  {num}
2212:~/mypy$ python3 stack54033455.py num -h
usage: test num [-h] [-n N] [-x X] [-y Y] [-z Z]

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

Required arguments:
  -x X
  -y Y
  -z Z
2212:~/mypy$ python3 stack54033455.py num -x foo
Namespace(n=None, x='foo', y=None, z=None)
2212:~/mypy$ python3 stack54033455.py num -y foo
Namespace(n=None, x=None, y='foo', z=None)
usage: test [-h] {num} ...
test: error: both y and z are required
2212:~/mypy$ python3 stack54033455.py num -y foo -z bar
Namespace(n=None, x=None, y='foo', z='bar')

Я исследовал возможность использования вложенных групп с обобщенной логикой в ​​https://bugs.python.org/issue11588 (добавление групп «обязательно включительно» в argparse).В настоящее время я думаю, что было бы неплохо предоставить вам доступ к набору seen_actions, чтобы вы могли проводить тестирование на использование без зависимости от теста is None.Форматировщик текущего использования слишком хрупок, чтобы его обобщать.

Использование:

num  = subparsers.add_parser("num", usage="test num [-h] [-n N] (-x X | (-y Y -z Z))")

работает.

...