Python optparse, значения по умолчанию и явные параметры - PullRequest
6 голосов
/ 08 ноября 2011

Возьмите следующий довольно стандартный код:

from optparse import OptionParser                         
opts = OptionParser()
opts.add_option('-f', action="store_true")
opts.add_option("-x", dest="x", type="int", default=1)
options, args = opts.parse_args()

Предположим, что -x и -f являются взаимоисключающими: когда -x и -f оба явно присутствуют, следует сообщить об ошибке.

Как определить, присутствует ли -x явно? Даже если это не так, options перечисляет значение по умолчанию.

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

Другим способом будет проверка sys.argv на наличие экземпляров -x, что тоже немного неудобно, если есть несколько имен для -x (то есть --long-name) и существует более одна пара взаимоисключающих опций.

Это элегантное решение для этого?

Ответы [ 2 ]

8 голосов
/ 08 ноября 2011

Вы можете сделать это с помощью optparse, используя обратный вызов.Сборка из вашего кода:

from optparse import OptionParser

def set_x(option, opt, value, parser):
    parser.values.x = value
    parser.values.x_set_explicitly = True

opts = OptionParser()
opts.add_option('-f', action="store_true")
opts.add_option("-x", dest="x", type="int", default=1, action='callback',
                callback=set_x)
options, args = opts.parse_args()
opts.values.ensure_value('x_set_explicitly', False)

if options.x_set_explicitly and options.f:
    opts.error('options -x and -f are mutually exclusive')

Давайте сейчас назовем этот скрипт op.py.Если я сделаю python op.py -x 1 -f, ответ будет:

Использование: op.py [опции]

op.py: ошибка: опции -x и -f являются взаимоисключающими

7 голосов
/ 08 ноября 2011

Используйте argparse .Есть раздел для взаимоисключающих групп :

argparse.add_mutually_exclusive_group (обязательно = False)

Создать взаимоисключающую группу.argparse будет следить за тем, чтобы в командной строке присутствовал только один из аргументов во взаимоисключающей группе:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_mutually_exclusive_group()
>>> group.add_argument('--foo', action='store_true')
>>> group.add_argument('--bar', action='store_false')
>>> parser.parse_args(['--foo'])
Namespace(bar=True, foo=True)
>>> parser.parse_args(['--bar'])
Namespace(bar=False, foo=False)
>>> parser.parse_args(['--foo', '--bar'])
usage: PROG [-h] [--foo | --bar]
PROG: error: argument --bar: not allowed with argument --foo

optparse все равно не рекомендуется.

...