python argparse с зависимостями

Я пишу сценарий, который имеет 2 аргумента, которые являются взаимоисключающими, и вариант, который имеет смысл только с одним из этих аргументов. Я пытаюсь настроить argparse так, чтобы он терпел неудачу, если вы вызываете его с аргументом, который не имеет смысла.

Чтобы было ясно:

-m -f имеет смысл

-s имеет смысл

-s -f должен выдавать ошибки

никакие аргументы не годятся.

Код у меня есть:

parser = argparse.ArgumentParser(description='Lookup servers by ip address from host file')
parser.add_argument('host', nargs=1,
            help="ip address to lookup")
main_group = parser.add_mutually_exclusive_group()
mysql_group = main_group.add_argument_group()
main_group.add_argument("-s", "--ssh", dest='ssh', action='store_true',
            default=False,
            help='Connect to this machine via ssh, instead of printing hostname')
mysql_group.add_argument("-m", "--mysql", dest='mysql', action='store_true',
            default=False,
            help='Start a mysql tunnel to the host, instead of printing hostname')
mysql_group.add_argument("-f", "--firefox", dest='firefox', action='store_true',
            default=False,
            help='Start a firefox session to the remotemyadmin instance')

Что не работает, так как выплевывает

 usage: whichboom [-h] [-s] [-m] [-f] host

а не то, что я ожидал:

 usage: whichboom [-h] [-s | [-h] [-s]] host

или что-то в этом роде.

 whichboom -s -f -m 116

также не выдает никаких ошибок.


person richo    schedule 16.12.2010    source источник


Ответы (2)


Вы просто перепутали группы аргументов. В вашем коде вы назначаете только одну опцию взаимоисключающей группе. Я думаю, что вы хотите:

parser = argparse.ArgumentParser(description='Lookup servers by ip address from host file')
parser.add_argument('host', nargs=1,
            help="ip address to lookup")
main_group = parser.add_mutually_exclusive_group()
mysql_group = main_group.add_argument_group()
main_group.add_argument("-s", "--ssh", dest='ssh', action='store_true',
            default=False,
            help='Connect to this machine via ssh, instead of printing hostname')
mysql_group.add_argument("-m", "--mysql", dest='mysql', action='store_true',
            default=False,
            help='Start a mysql tunnel to the host, instead of printing hostname')
main_group.add_argument("-f", "--firefox", dest='firefox', action='store_true',
            default=False,
            help='Start a firefox session to the remotemyadmin instance')

Вы можете просто пропустить всю взаимоисключающую группу и добавить что-то вроде этого:

usage = 'whichboom [-h] [-s | [-h] [-s]] host'
parser = argparse.ArgumentParser(description, usage)
options, args = parser.parse_args()
if options.ssh and options.firefox:
    parser.print_help()
    sys.exit()
person user545424    schedule 16.12.2010
comment
Это функциональный обходной путь. Я настрою его на бомбардировку с недопустимыми параметрами, но я чувствую, что это бесполезно. Если я не смогу разобраться с этим сегодня утром, я пойду беспокоить разработчиков, это может быть ошибка. - person richo; 17.12.2010
comment
Я добавляю группу mysql и еще один вариант во взаимно_исключающую_группу. Полагаю, я ожидал возможности исключить другую группу, но это не так. Я закончил с вашим другим решением. - person richo; 20.12.2010
comment
argument group и mutually exclusive group имеют очень разные цели и не могут быть осмысленно вложены. argument_group не означает any of the above. - person hpaulj; 31.03.2017

Добавьте аргумент usage при создании парсера:

usage = "usage: whichboom [-h] [-s | [-h] [-s]] host"
description = "Lookup servers by ip address from host file"
parser = argparse.ArgumentParser(description=description, usage=usage)

Источник: http://docs.python.org/dev/library/argparse.html#usage

person Andrew Clark    schedule 16.12.2010
comment
В лучшем случае это исправляет печать из командной строки, не нарушает функциональность (программа принимает неверный набор аргументов) и означает, что мне приходится поддерживать эту строку вручную. на случай, если это поможет кому-то понять, что происходит. - person richo; 17.12.2010