У меня есть следующие требования:
./xyifier --prox --lport lport --rport rport
для аргумента prox я использую action = 'store_true', чтобы проверить, присутствует он или нет. Я не нуждаюсь ни в каких аргументах. Но, если установлен --prox, мне также нужны rport и lport. Есть ли простой способ сделать это с помощью argparse без написания пользовательского условного кодирования.
Больше кода:
non_int.add_argument('--prox', action='store_true', help='Flag to turn on proxy')
non_int.add_argument('--lport', type=int, help='Listen Port.')
non_int.add_argument('--rport', type=int, help='Proxy port.')
Ответы:
Нет, в argparse нет возможности создавать взаимно включающие наборы параметров.
Самый простой способ справиться с этим:
источник
parser.error
метод, это то, что я искал!if args.prox and (args.lport is None or args.rport is None):
args.lport is None
вы можете просто использоватьnot args.lport
. Я думаю, это немного более питоническое.--lport
или--rport
к0
, который может быть действительным вкладом в программу.Вы говорите об условно обязательных аргументах. Как сказал @borntyping, вы можете проверить наличие ошибки и сделать это
parser.error()
, или вы можете просто применить требование, связанное с--prox
добавлением нового аргумента.Простым решением для вашего примера может быть:
Этот способ
required
получает либо,True
либо вFalse
зависимости от того, используется ли пользователь--prox
. Это также гарантирует, что-lport
и-rport
независимое поведение друг с другом.источник
ArgumentParser
это можно использовать для анализа аргументов из другого списка, кроме тогоsys.argv
, в этом случае это не сработает.--prox=<value>
синтаксис.Как об использовании
parser.parse_known_args()
метода , а затем добавляя--lport
и--rport
арг , как это требуется , если арг--prox
присутствует.Также имейте в виду, что вы можете предоставить пространство имен,
opts
сгенерированное после первого синтаксического анализа, во время синтаксического анализа оставшихся аргументов во второй раз. Таким образом, в конце концов, после того, как весь анализ будет выполнен, у вас будет единое пространство имен со всеми параметрами.Недостатки:
--prox
отсутствует, две другие зависимые опции даже не присутствуют в пространстве имен.--prox
То, что происходит с другими параметрами, не имеет значения, хотя и зависит от вашего варианта использования.--lport
и--rport
не отображаются в справочном сообщенииисточник
Вы используете,
lport
когдаprox
не установлен. Если нет, то почему бы не сделатьlport
иrport
аргументыprox
? напримерЭто избавляет ваших пользователей от набора текста. Его так же легко проверить,
if args.prox is not None:
какif args.prox:
.источник
a,b = args.prox
,a = args.prox[0]
и т.д.Принятый ответ отлично сработал для меня! Поскольку весь код сломан без тестов, вот как я проверил принятый ответ.
parser.error()
не вызываетargparse.ArgumentError
ошибку, а выходит из процесса. Вы должны проверитьSystemExit
.с pytest
с юнит-тестами
Вдохновленный: Использование unittest для тестирования argparse - ошибки выхода
источник