Да, има начин, но той използва някои скрити атрибути на анализатора. Използвам идея, разработена за
http://bugs.python.org/issue10984 argparse add_mutually_exclusive_group should accept existing arguments to register conflicts
Създайте 2 родителски парсера с add_help=False
(за да предотвратите конфликти около аргумента -h
- това е стандартна процедура за родителски анализатор)
a_parser = argparse.ArgumentParser(add_help=False)
aaAction = a.parser.add_argument('-a')
b_parser = argparse.ArgumentParser(add_help=False)
bbAction = b_parser.add_argument('-b')
parser=argparse.ArgumentParser(parents=[a_parser, b_parser])
group=parser.add_mutually_exclusive_group()
В този момент parser
има 3 действия (аргументи), които могат да се видят в атрибут „private“, _actions
:
print parser._actions
"""
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=['-a'], dest='a', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None),
_StoreAction(option_strings=['-b'], dest='b', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
"""
Първата е собствена help
, другите са наследени от родителите. Също така запазих указатели към тези по-рано, aaAction
и bbAction
. Сега просто трябва да добавим тези към списъка _group_actions
от group
:
group._group_actions.append(parser._actions[1]) # or (aaAction)
group._group_actions.append(parser._actions[2]) # or (bbAction)
Ако корекция 10984 беше приложена, можехме да напишем:
group = parser.add_mutually_exclusive_group(aaAction, bbAction)
който би изпълнил това добавяне като част от създаването на групата.
Можем да го тестваме с:
In [31]: print parser.format_help()
usage: ipython [-h] [-a A | -b B]
optional arguments:
-h, --help show this help message and exit
-a A
-b B
In [32]: parser.parse_args(['-a','a'])
Out[32]: Namespace(a='a', b=None)
In [33]: parser.parse_args(['-a','a','-b','b'])
usage: ipython [-h] [-a A | -b B]
ipython: error: argument -b: not allowed with argument -a
An exception has occurred, use %tb to see the full traceback.
Това зависи от няколко части от информацията:
add_argument
връща указател към току-що създаденото действие.
parents
добавя действия към новия анализатор само чрез копиране на точки за действие, т.е. чрез препратка.
знаейки къде parse
и group
съхраняват съответните си списъци с действия.
да знаете как добавянето на действие към група се различава от добавянето му към анализатор (не много).
Препоръчвам да тествате код като този в интерактивна обвивка (като IPython
), където можете да разгледате атрибутите на parser
и group
. И дръжте копие на Lib/argparse.py
под ръка. :)
кръпка 10984 има добавен код за справяне с усложнението от наличието на действие в повече от една група. Обикновено едно действие принадлежи само към една група.
person
hpaulj
schedule
23.01.2015