2010-12-30 14 views
5

Sto usando argparse per gestire cmd args, voglio se non ci sono argomenti specificati, quindi stampare il messaggio di aiuto, ma ora l'analisi genera un errore, e quindi esci. il mio codice è:come lasciare che il parser stampi un messaggio di aiuto piuttosto che un errore ed esca

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 

come posso farlo? grazie.

+0

* ora l'analisi genera un errore, quindi esce * - Che errore si ottiene? –

+0

è un errore: troppo pochi argomenti – fluter

risposta

3

Una soluzione consiste nella sottoclasse argparse.ArgumentParser e nella ridefinizione del metodo error(). Infatti, in caso di errore, ArgumentParser chiama il suo metodo error(). L'analisi dell'argomento personalizzato può quindi essere eseguita tramite la sottoclasse anziché argparse.ArgumentParser. Una funzione del modello error() si trova nella sorgente per 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)) 

E 'per esempio possibile sollevare un'eccezione in error(), invece di stampare un messaggio, in modo che il codice chiamante parse_args() si fa carico dei problemi con l'utente parametri.

Risposta originale: in base al chiarimento nei commenti, quanto segue non funziona. Tuttavia, fornisce un meccanismo per l'accesso ai messaggi di aiuto dalle funzioni sub-comando:

È quasi ce l'ha: in ciascuno dei vostri *_command(args) funzioni, è possibile verificare le dimensioni del args e stampare un messaggio di errore se non ci sono abbastanza argomenti.

Se si desidera utilizzare l'aiuto generato automaticamente, nelle funzioni di comando, si può ottenere facendo passare le subparsers per ogni comando, in questo modo:

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

Ogni funzione *_command() dovrebbe poi semplicemente prendere due argomenti invece di uno. L'aiuto generato automaticamente è accessibile tramite:

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

per esempio.

Si potrebbe in alternativa scegliere di passare direttamente alla particolare subparser ad ogni sub-routine di comando *_command():

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

e poi, in ogni *_command(subparser, args), stampare la guida con subparser.print_help().

+0

il problema è che si verificheranno errori e uscite quando si chiama parser.parse_args(), quindi non c'è alcuna possibilità di chiamare args.command (subparsers, args) se non viene fornito alcun argomento. – fluter

+1

@fluter: vedo. Ho aggiornato il mio post con una soluzione. :) – EOL

Problemi correlati