2013-02-06 15 views
31

Non penso che sia possibile, ma voglio gestire le eccezioni da Argparse me stesso.Voglio che Python argparse lanci un'eccezione piuttosto che l'uso

Ad esempio:

import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument('--foo', help='foo help', required=True) 
try: 
    args = parser.parse_args() 
except: 
    do_something() 

quando l'eseguo:

$ myapp.py 
usage: myapp --foo foo 
myapp: error: argument --foo is required 

Ma voglio che cadere nella un'eccezione, invece.

+2

Non stai utilizzando argparse per quello che è stato progettato, quindi. Che cosa vuoi fare? –

+9

Non è una brutta cosa cambiare il modo in cui funziona una libreria altrimenti fantastica, solo per sintonizzarla su un particolare progetto. – jdborg

+4

In realtà puoi già farlo. semplicemente prendi 'SystemExit' e sostituisci' sys.stderr' con qualche altro oggetto. – Bakuriu

risposta

55

È possibile sottoclasse ArgumentParser e l'override del metodo error di fare qualcosa di diverso quando si verifica un errore:

class ArgumentParserError(Exception): pass 

class ThrowingArgumentParser(argparse.ArgumentParser): 
    def error(self, message): 
     raise ArgumentParserError(message) 

parser = ThrowingArgumentParser() 
parser.add_argument(...) 
... 
+0

Pensavo che sarebbe stato qualcosa del genere. Grazie per la risposta chiara. – jdborg

+3

Speravo di evitare qualcosa di simile, anche se sono contento che sia un'opzione. Vedete, sto cercando di stampare il menu di aiuto quando ricevo una notifica di "errore: troppo pochi argomenti"; il mio setup argparse richiede almeno un argomento per funzionare correttamente, ma immagino che sarebbe educato stampare quali sono quei comandi senza che l'utente debba eseguire lo script con il parametro "-h". Qualcosa di simile: 'parser.set_error ('too few arguments', method_to_deal_with_error)' Suppongo di poter sempre segnalare un errore se voglio questa funzione. Grazie! – NuclearPeon

12

nel mio caso, stampe argparse 'troppo pochi argomenti' poi smettere. dopo aver letto il codice argparse, ho trovato semplicemente sys.exit() dopo aver stampato un messaggio. siccome sys.exit() non fa altro che lanciare un'eccezione SystemExit, puoi semplicemente catturare questa eccezione.

quindi prova questo per vedere se funziona per voi.

try: 
     args = parser.parse_args(args) 
    except SystemExit: 
     .... your handler here ... 
     return 
+1

Sì, questa opzione è menzionata sopra nel commento di Bakuriu. Il file 'test_argparse.py' non testato utilizza questo approccio, insieme alla ridefinizione di' error' per creare una classe 'ErrorRaisingArgumentParser'. – hpaulj

+3

il messaggio di errore viene scartato su stderr. C'è un modo per prenderlo? – Raj

+1

@Raj È possibile reindirizzare temporaneamente lo stderr a un altro oggetto stream/file, ad esempio: https://stackoverflow.com/a/6796752/2128769 – umi

Problemi correlati