Да, способ есть, но он использует какие-то скрытые атрибуты парсера. Я использую идею, разработанную для
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)]
"""
1-й собственный 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