Tengo un requisito de la siguiente manera:
./xyifier --prox --lport lport --rport rport
para el argumento prox, uso action = 'store_true' para verificar si está presente o no. No necesito ninguno de los argumentos. Pero, si --prox se establece que requiero rport y lport también. ¿Existe una manera fácil de hacer esto con argparse sin escribir codificación condicional personalizada?
Más código:
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.')
Respuestas:
No, no hay ninguna opción en argparse para hacer conjuntos de opciones mutuamente inclusivos .
La forma más sencilla de lidiar con esto sería:
fuente
parser.error
método, ¡esto es lo que estaba buscando!if args.prox and (args.lport is None or args.rport is None):
args.lport is None
, simplemente puede usarnot args.lport
. Creo que es un poco más pitónico.--lport
o--rport
que0
, lo que podría ser una entrada válida para el programa.Estás hablando de tener argumentos requeridos condicionalmente. Como dijo @borntyping, puede verificar el error y hacerlo
parser.error()
, o simplemente puede aplicar un requisito relacionado con el--prox
momento en que agrega un nuevo argumento.Una solución simple para su ejemplo podría ser:
De esta forma
required
recibeTrue
oFalse
dependiendo de si el usuario lo utiliza--prox
. Esto también garantiza que-lport
y-rport
tengan un comportamiento independiente entre sí.fuente
ArgumentParser
se puede utilizar para analizar argumentos de una lista distinta desys.argv
, en cuyo caso esto fallaría.--prox=<value>
se usa la sintaxis.¿Qué tal si usamos el
parser.parse_known_args()
método y luego agregamos los argumentos--lport
y los--rport
argumentos requeridos si--prox
está presente?También tenga en cuenta que puede proporcionar el espacio de nombres
opts
generado después del primer análisis mientras analiza los argumentos restantes la segunda vez. De esa manera, al final, después de que se haya realizado todo el análisis, tendrá un solo espacio de nombres con todas las opciones.Inconvenientes:
--prox
no está presente, las otras dos opciones dependientes ni siquiera están presentes en el espacio de nombres. Aunque se basa en su caso de uso, si--prox
no está presente, lo que sucede con las otras opciones es irrelevante.--lport
y--rport
no aparezcas en el mensaje de ayudafuente
¿Lo usa
lport
cuandoprox
no está configurado? Si no, ¿por qué no hacerlport
yrport
argumentarprox
? p.ejEso les ahorra a sus usuarios escribir. Es tan fácil de probar
if args.prox is not None:
comoif args.prox:
.fuente
a,b = args.prox
,a = args.prox[0]
, etc.¡La respuesta aceptada funcionó muy bien para mí! Dado que todo el código está roto sin pruebas, así es como probé la respuesta aceptada.
parser.error()
no genera unargparse.ArgumentError
error, sino que sale del proceso. Tienes que probarSystemExit
.con pytest
con unittests
inspirado en: Uso de unittest para probar argparse - errores de salida
fuente