2010-12-16 4 views
12

Я пишу скрипт, который имеет 2 аргумента, которые являются взаимоисключающими, и параметр, который имеет смысл только с одним из этих аргументов. Я пытаюсь настроить argparse для отказа, если вы вызываете его с аргументом, который не имеет смысла.python 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 

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

ответ

8

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

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() 
+1

Это функциональное обходное решение. Я настроюсь на то, чтобы бомбить с недействительными вариантами, но я чувствую, что это kludge. Если я не смогу разобраться с этим сегодня утром, я пойду наперекор разработчикам, это может быть ошибка. – richo 2010-12-16 23:12:42

2

Добавьте 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

+1

Это в лучшем случае фиксирует печать командной строки, он не Unbreak функциональность (программа принимает недопустимый набор аргументов) и означает, что я должен поддерживать эту линию вручную. Линия использования - это наименьшая из моих проблем, я включил ее в основном в том случае, если это поможет кому-то понять, что происходит. – richo 2010-12-16 23:09:54