Esta respuesta proviene de Steven Bethard en los grupos de Google . Lo vuelvo a publicar aquí para facilitar el acceso de las personas sin una cuenta de Google.
Puede anular el comportamiento predeterminado del error
método:
import argparse
import sys
class MyParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n' % message)
self.print_help()
sys.exit(2)
parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()
Tenga en cuenta que la solución anterior imprimirá el mensaje de ayuda cada vez que se active el error
método. Por ejemplo, test.py --blah
también imprimirá el mensaje de ayuda si --blah
no es una opción válida.
Si desea imprimir el mensaje de ayuda solo si no se proporcionan argumentos en la línea de comando, entonces quizás esta sea la forma más fácil:
import argparse
import sys
parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
parser.print_help(sys.stderr)
sys.exit(1)
args=parser.parse_args()
Tenga en cuenta que parser.print_help()
imprime en stdout de forma predeterminada. Como init_js sugiere , use parser.print_help(sys.stderr)
para imprimir en stderr.
parser.print_usage()
en lugar deparser.print_help()
: el mensaje de ayuda incluye el uso, pero es más detallado.error()
parece una idea terrible. Tiene un propósito diferente, no está diseñado para imprimir un uso amigable o ayuda.En lugar de escribir una clase, se puede usar un try / except en su lugar
Lo bueno es que el flujo de trabajo es más claro y no necesita una clase de código auxiliar. La desventaja es que la primera línea de 'uso' se imprime dos veces.
Esto necesitará al menos un argumento obligatorio. Sin argumentos obligatorios, es válido proporcionar cero argumentos en la línea de comandos.
fuente
-h
se usa el indicador, y las impresiones innecesarias ayudan si--version
se usa el indicador. Para mitigar esos problemas, puede verificar un tipo de error como este:except SystemExit as err: if err.code == 2: parser.print_help()
Con argparse podrías hacer:
fuente
parser.parse_args()
Si tiene argumentos que deben especificarse para que se ejecute el script, use el parámetro requerido para ArgumentParser como se muestra a continuación:
parse_args () informará un error si el script se ejecuta sin ningún argumento.
fuente
Si asocia funciones predeterminadas para (sub) analizadores, como se menciona a continuación
add_subparsers
, simplemente puede agregarlo como la acción predeterminada:Agregue el try, excepto si genera excepciones debido a la falta de argumentos posicionales.
fuente
La solución más limpia será pasar manualmente el argumento predeterminado si no se dio ninguno en la línea de comando:
Ejemplo completo:
Esto imprimirá ayuda completa (no uso corto) si se llama sin argumentos.
fuente
sys.argv[1:]
Es un idioma muy común. Veoparser.parse_args(None if sys.argv[1:] else ['-h'])
más idiomático y más limpio.Lanzando mi versión a la pila aquí:
Puede notar el
parser.exit
- Principalmente lo hago así porque guarda una línea de importación si esa era la única razónsys
en el archivo ...fuente
not vars(args)
puede no funcionar cuando los argumentos tienendefault
método.Hay un par de frases con
sys.argv[1:]
(un lenguaje muy común de Python para referirse a los argumentos de la línea de comandos, que essys.argv[0]
el nombre del script) que pueden hacer el trabajo.El primero se explica por sí mismo, es limpio y pitónico:
El segundo es un poco más pirateado. Combinando el hecho evaluado previamente de que hay una lista vacía
False
con las equivalenciasTrue == 1
yFalse == 0
obtienes esto:Quizás demasiados corchetes, pero bastante claro si se realizó una selección de argumento anterior.
fuente
El
parser.exit
método también acepta unstatus
(código de retorno) y unmessage
valor (¡incluya una nueva línea final usted mismo!).un ejemplo obstinado :)
Llamadas de ejemplo:
fuente
Establezca sus argumentos posicionales con nargs y verifique si los argumentos posicionales están vacíos.
Nargs de referencia de Python
fuente
Aquí hay otra forma de hacerlo, si necesita algo flexible donde desea mostrar ayuda si se pasan parámetros específicos, ninguno en absoluto o más de 1 argumento en conflicto:
¡Salud!
fuente
Si su comando es algo donde un usuario necesita elegir alguna acción, entonces use un grupo mutuamente exclusivo con required = True .
Esta es una especie de extensión de la respuesta dada por pd321.
Salida:
Esto solo da la ayuda básica. Y algunas de las otras respuestas le brindarán toda la ayuda. Pero al menos tus usuarios saben que pueden hacer -h
fuente
Esto no es bueno (también, porque intercepta todos los errores), pero:
Aquí está la definición de la
error
función de laArgumentParser
clase:https://github.com/python/cpython/blob/276eb67c29d05a93fbc22eea5470282e73700d20/Lib/argparse.py#L2374
. Como puede ver, después de la firma, se necesitan dos argumentos. Sin embargo, las funciones fuera de la clase no saben nada sobre el primer argumento:
self
porque, en términos generales, este es un parámetro para la clase. (Lo sé, que usted sabe ...) Por lo tanto, sólo tiene que pasar propiaself
ymessage
en_error(...)
no puede (dará salida:
) Puede pasar
parser
(self
) en_error
función, llamándolo:, pero no quieres salir del programa, ahora mismo. Luego devuélvelo:
. Sin embargo,
parser
no sabe que se ha modificado, por lo tanto, cuando se produce un error, enviará la causa (por cierto, su traducción localizada). Bueno, entonces interceptarlo:. Ahora, cuando ocurre un error y
parser
enviará la causa del mismo, lo interceptarás, mirarás esto y ... lo arrojarás.fuente