2015-09-17 2 views
4

Я использую argparse для управления параметрами командной строки, и я хочу управлять двумя вариантами: --check и --nocheck. Я на самом деле делать что-то подобное в mybadscript.py:Как управлять приоритетом в argparse?

[...] 
args = parser.parse_args() 

if args.check: 
    check = True 

if args.nocheck: 
    check = False 
[...] 

Проблема заключается в том, что если запустить скрипт так:

python mybadscript.py --nocheck --check

check будет установлен в False. Это неверно, поскольку последний параметр - --check.

Как я могу правильно ими управлять?

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

PPS: предлагаемый ответ, кстати, отвечает на мой вопрос, но связанный с ним вопрос не является тем же.

+1

Возможный обман? Http: // StackOverflow.com/q/15008758/748858 – mgilson

+0

Основной момент заключается в том, что ваш пользователь контролирует приоритет - последняя строка опции имеет окончательное значение для значения. Если вам это не нравится, вам нужно использовать специальные классы 'action' и' dest' для определения и использования более ранних строк. – hpaulj

ответ

6

См. argparse documentation. Вот пример того, что вы можете пожелать. Я включил несколько вариантов, которые вам могут не понадобиться, - я думал, что это лучше, чем оставить их, и вам нужно их.

>>> parser = argparse.ArgumentParser() 
>>> group = parser.add_mutually_exclusive_group(required=True) 
>>> group.add_argument('--check', action='store_true', dest="check") 
>>> group.add_argument('--nocheck', action='store_false', dest="check") 
>>> parser.parse_args(["--check"]) 
Namespace(check=True) 
>>> parser.parse_args(["--nocheck"]) 
Namespace(check=False) 

Вы не можете хотеть взаимоисключающую часть в этом случае удалите вторую строку и заменить group с parser. Если вы сделаете так, вы можете добавить эту строку:

>>> parser.set_defaults(check=False) 
+1

Взаимная исключительная группа обходит реальный вопрос, так как теперь невозможно использовать оба варианта, ставя вопрос о приоритете спорным. В противном случае, хороший ответ. Я бы использовал 'set_defaults', чтобы установить значение' check' в случае, если не используется * опция *. – chepner

+0

@chepner Я добавил ссылку на 'set_defaults', но во второй строке я говорю' required = True', обойдя проблему пользователя, не предоставляющего предпочтения. – robert

+0

Спасибо, я пропустил 'dest'. В любом случае, это не полностью заполняет мое любопытство, но на этот вопрос отвечает. Я открою еще один вопрос о позиции опциона. –

1

У вас есть два аргумента, которые независимо друг от друга, установленных две различных атрибутов пространств имен, args.check и args.nocheck. С линией ввода --nocheck --check оба установлены.

В:

if args.check: 
    check = True 
if args.nocheck: 
    check = False 

вы тестируете nocheck последнего, так что один приоритет check.

argparse пытается обрабатывать опции (помеченные аргументы) в порядке, независимом от заказа.

Если они пишут в одно и то же «dest», это последнее, что вы в конечном итоге увидите. Один из способов, чтобы увидеть то, что было введено, и в каком порядке, чтобы использовать «Добавить» действие:

parser=argparse.ArgumentParser() 
parser.add_argument('--check', dest='checked', action='append_const', const=True) 
parser.add_argument('--nocheck', dest='checked', action='append_const', const=False) 

In [14]: parser.parse_args(''.split()) # no arg 
Out[14]: Namespace(checked=None) 

я мог сделать по умолчанию []

In [15]: parser.parse_args('--check'.split()) 
Out[15]: Namespace(checked=[True]) 

In [16]: parser.parse_args('--nocheck'.split()) 
Out[16]: Namespace(checked=[False]) 

In [17]: parser.parse_args('--nocheck --check --nocheck'.split()) 
Out[17]: Namespace(checked=[False, True, False]) 

Спаренные «store_true» и 'store_false' в другом ответе проще.

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

Смежные вопросы