2015-02-16 2 views
1

У меня есть следующие:argparse с argument_groups и mututally_exclusive_group

def parser(): 
    p = argparse.ArgumentParser() 
    people = p.add_argument_group('people_list') 
    meg = people.add_mutually_exclusive_group() 
    meg.add_argument('--config-file') 
    g = meg.add_argument_group('people') 
    g.add_argument('--name') 
    g.add_argument('--age') 
    return p 

p = parser() 

p.parse_args(['--config-file', 'cfg_file', '--name', 'Bob', '--age', '3']) 

я ожидаю, что это будет жаловаться в связи с mutually_exclusive группы. Обратите внимание, что это фрагмент фактического кода, у меня есть несколько argument_groups, с которыми мне нужно работать, но в этом argument_group('people_list') я хочу, чтобы пользователь указывал либо файл конфигурации, либо любой другой аргумент.

Итак, мой пользователь должен быть в состоянии сказать

prog --config-file cfg_file 

или

prog --name Bob --age 3 

но не

prog --config-file cfg_file --name Bob --age 3 

Что я здесь делаю неправильно?

+0

Я ожидаю, что он будет бросать исключение из-за 'devices' быть ссылки, прежде чем определить и/или не имеющие атрибут' add_mutually_exclusive_group' ... – twalberg

+0

@twalberg. Тип, фиксированный. Должны были люди – Mark

ответ

1

Вот помощь:

usage: foo [-h] [--config-file CONFIG_FILE] [--name NAME] 
         [--age AGE] 

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

people_list: 
    --config-file CONFIG_FILE 

Аргумент группы, как people управляет тем, как показаны на линии помощи. Следовательно, раздел под названием people_list.

Независимая группа контролирует, как используется форматирование, и проверяет cooccurance аргументов. Технически это подкласс группы аргументов, но два типа групп мало взаимодействуют.

Вы можете вставить взаимно исключающую группу в группу аргументов, как вы это делали. Но вы не можете вложить группу аргументов в другую группу (либо вид). Вернее, он примет такое определение, но он ничего особенного не делает. Таким образом, name и age были добавлены в парсер (как видно из использования), но не до meg или people. И если вы добавите взаимоисключающую группу в другую MXGroup, эффект состоит в том, чтобы просто создать большую плоскую группу.

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

Если добавить name и age к meg, то помочь будет:

usage: foo [-h] 
         [--config-file CONFIG_FILE | --name NAME | --age AGE] 

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

people_list: 
    --config-file CONFIG_FILE 
    --name NAME 
    --age AGE 

Это будет возражать против использования config-file либо name или age. Но он также будет возражать против использования как name, так и age.

Существует проблема с ошибкой, которая запрашивает обобщенные вложенные взаимно-ххх-группы. После реализации он может справиться с этой обобщенной логикой. Но пока это невозможно. Предполагая, что вы можете настроить те тесты, которые вы хотите, какова будет идеальная линия использования? Сравнительно легко настроить тесты, но гораздо сложнее создать осмысленное использование.

На данный момент я предлагаю написать свой собственный usage. Используйте argument groups для группировки строк справки аргумента. Соблюдайте свои собственные тесты взаимодействия после разбора. Вы можете использовать p.error... для генерации сообщений об ошибках. И если вы правильно выбираете значения по умолчанию, нетрудно проверить аргументы, например.

if args.config_file is not None and 
    (args.name is not None or args.age is not None): 
    p.error('...')