2010-12-30 3 views
5

Estoy usando argparse para manejar cmd args, quiero si no hay argumentos especificados, luego imprimo el mensaje de ayuda, pero ahora el análisis generará un error, y luego salga mi código es:cómo dejar que el analizador imprima un mensaje de ayuda en lugar de un error y salga

def main(): 
    print "in abing/start/main" 
    parser = argparse.ArgumentParser(prog="abing")#, usage="%(prog)s <command> [args] [--help]") 
    parser.add_argument("-v", "--verbose", action="store_true", default=False, help="show verbose output") 

    subparsers = parser.add_subparsers(title="commands") 

    bkr_subparser = subparsers.add_parser("beaker", help="beaker inspection") 
    bkr_subparser.set_defaults(command=beaker_command) 
    bkr_subparser.add_argument("-m", "--max", action="store", default=3, type=int, help="max resubmit count") 
    bkr_subparser.add_argument("-g", "--grain", action="store", default="J", choices=["J", "RS", "R", "T", "job", "recipeset", "recipe", "task"], type=str, help="resubmit selection granularity") 
    bkr_subparser.add_argument("job_ids", nargs=1, action="store", help="list of job id to be monitored") 

    et_subparser = subparsers.add_parser("errata", help="errata inspection") 
    et_subparser.set_defaults(command=errata_command) 
    et_subparser.add_argument("-w", "--workflows", action="store_true", help="generate workflows for the erratum") 
    et_subparser.add_argument("-r", "--run", action="store_true", help="generate workflows, and run for the erratum") 
    et_subparser.add_argument("-s", "--start-monitor", action="store_true", help="start monitor the errata system") 
    et_subparser.add_argument("-d", "--daemon", action="store_true", help="run monitor into daemon mode") 
    et_subparser.add_argument("erratum", action="store", nargs=1, metavar="ERRATUM", help="erratum id") 

    if len(sys.argv) == 1: 
     parser.print_help() 
     return 

    args = parser.parse_args() 
    args.command(args) 

    return 

¿cómo puedo hacer eso? gracias.

+0

* ahora el análisis generará un error y luego saldrá * - ¿Qué error obtiene? –

+0

es un error: muy pocos argumentos – fluter

Respuesta

3

Una solución consiste en la subclasificación de argparse.ArgumentParser y la redefinición de su método error(). De hecho, en caso de error, ArgumentParser llama a su método error(). El análisis de argumento personalizado se puede realizar a través de la subclase en lugar de argparse.ArgumentParser. Una función de modelo error() se encuentra en la fuente de argparse:

def error(self, message): 
    """error(message: string) 

    Prints a usage message incorporating the message to stderr and 
    exits. 

    If you override this in a subclass, it should not return -- it 
    should either exit or raise an exception. 
    """ 
    self.print_usage(sys.stderr) 
    self.exit(2, '%s: error: %s\n' % (self.prog, message)) 

Por ejemplo, es posible elevar una excepción en error(), en lugar de imprimir un mensaje, por lo que el código de llamada parse_args() se hace cargo de los problemas con el usuario parámetros.

Respuesta original: de acuerdo con la aclaración en los comentarios, el siguiente no funciona. Sin embargo, proporciona un mecanismo para acceder a los mensajes de ayuda desde las funciones de submandato:

Casi lo tiene: en cada una de sus funciones *_command(args), puede probar el tamaño de args e imprimir un mensaje de error si no hay suficientes argumentos.

Si desea utilizar la ayuda generada automáticamente, en sus funciones de mando, lo puede conseguir haciendo pasar los subparsers a cada comando, así:

args.command(subparsers, args) # Instead of args.command(args) 

Cada función *_command() debe entonces simplemente tomar dos argumentos en lugar de uno Se puede acceder a la ayuda generada automáticamente a través de:

subparsers.choices['beaker'].print_help() # or print_usage() 

por ejemplo.

Se podría, alternativamente, optar por pasar directamente al subparser particular, para cada sub-rutina de comando *_command():

args.command(subparsers.choices[sys.argv[1]], args) 

y luego, en cada *_command(subparser, args), impresión de la ayuda con subparser.print_help().

+0

el problema es que generará un error y saldrá al llamar a parser.parse_args(), por lo que no hay posibilidad de llamar a args.command (subparsers, args) si no se proporciona args. – fluter

+1

@fluter: Ya veo. Actualicé mi publicación con una solución. :) – EOL

Cuestiones relacionadas