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.errormé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.--lporto--rportque0, 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--proxmomento en que agrega un nuevo argumento.Una solución simple para su ejemplo podría ser:
De esta forma
requiredrecibeTrueoFalsedependiendo de si el usuario lo utiliza--prox. Esto también garantiza que-lporty-rporttengan un comportamiento independiente entre sí.fuente
ArgumentParserse 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--lporty los--rportargumentos requeridos si--proxestá presente?También tenga en cuenta que puede proporcionar el espacio de nombres
optsgenerado 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:
--proxno 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--proxno está presente, lo que sucede con las otras opciones es irrelevante.--lporty--rportno aparezcas en el mensaje de ayudafuente
¿Lo usa
lportcuandoproxno está configurado? Si no, ¿por qué no hacerlportyrportargumentarprox? 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.ArgumentErrorerror, sino que sale del proceso. Tienes que probarSystemExit.con pytest
con unittests
inspirado en: Uso de unittest para probar argparse - errores de salida
fuente