2016-05-18 3 views
1

Так что я использую argparse, и я пытаюсь создать что-то, что я, похоже, не могу найти в любом месте.Группа в группе ArgParse

Я пытаюсь сделать [A | [B C]]. Поэтому либо у меня есть A, либо (B and C).

EDIT Таким образом, некоторые из примеров кода будет

parser = argparse.ArgumentParser() 
group = parser.add_mutually_exclusive_group(required=False) 
group.add_argument("-a") 
more = group.add_mutually_exclusive_group() 
more.add_argument("-b") 
more.add_argument("c") 

Это, однако, в конечном итоге дает мне [A | [B | C]]

+1

Похоже, что вам нужны [подкоманды] (https://docs.python.org/3/library/argparse.html#sub-commands), но дополнительная информация и некоторый пример кода были бы полезны. – ChrisP

ответ

1

Механизм взаимоисключающей группы предназначен только для простого (плоского) эксклюзивного или группового. Не существует механизма вложения одной группы в другую или для применения другой логики (and, any и т. Д.).

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

Subparsers предоставляют другую логику группировки, которая может работать на вас.

Это было поднято в других вопросах SO и проблема/проблема Python, если вам нужно изучить его более подробно.

===============

argument groups, несмотря на название, не работает с взаимоисключающими группами. Их цель цели совершенно другая (группировка линий помощи). Вы можете вложить одну взаимоисключающую группу в другую, но чистый эффект состоит в том, чтобы поместить все в одну группу.

argparse: some mutually exclusive arguments in required group

============================

import argparse 

usage = '%(prog)s [A | [B ? C]]' 
parser = argparse.ArgumentParser(usage=usage) 
parser.add_argument('-a') 
parser.add_argument('-b') 
parser.add_argument('-c') 
args=parser.parse_args() 

print(args) 
if args.a is not None: 
    if not(args.b is None and args.c is None): 
     parser.error('Cannot use b or c with a') 

с результатом пробегов

1722:~/mypy$ python3 stack37311550.py -a 1 
Namespace(a='1', b=None, c=None) 
1726:~/mypy$ python3 stack37311550.py -a 1 -b2 
Namespace(a='1', b='2', c=None) 
usage: stack37311550.py [A | [B ? C]] 
stack37311550.py: error: Cannot use b or c with a 
1726:~/mypy$ python3 stack37311550.py -c3 -b2 
Namespace(a=None, b='2', c='3') 
1726:~/mypy$ python3 stack37311550.py -c3 -b2 -a1 
Namespace(a='1', b='2', c='3') 
usage: stack37311550.py [A | [B ? C]] 
stack37311550.py: error: Cannot use b or c with a 
1
import argparse 

parser = argparse.ArgumentParser(description='test group') 
subparsers = parser.add_subparsers(help='sub-commands help') 
sp = subparsers.add_parser('A', help='A command') 
sp.set_defaults(cmd = 'A') 
sp = subparsers.add_parser('B', help='B command') 
sp.set_defaults(cmd = 'B') 
sp.add_argument('C', help='C option') 

args = parser.parse_args() 

if (args.cmd == 'A'): 
    print("running A mode") 
else: 
    print("running B mode with C=%s" % args.C) 

Вот журнал выполнения:

$ python test.py A 
running A mode 
$ python test.py B 
usage: test.py B [-h] C 
$ python test.py B some 
running B mode with C=some 

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

Смежные вопросы