2017-02-15 2 views
0

Ist es möglich, einen Fehler zu finden, der ausgelöst wird, wenn der Wert falsch mit argparse ist (ungültiger Wert, aber das Argument wird erkannt), um zu sehen, was den Fehler verursacht hat und schließlich ignorieren es (weiter mit dem Parsen)?Wie fangen Sie den Wert ab, der bewirkt, dass argparse einen Fehler in Python verursacht

Ich weiß, dass ich die Fehlermethode des ArgumentParser überschreiben kann, aber es gibt nur die Fehlermeldung als Zeichenfolge, und ich möchte vermeiden, diese Zeichenfolge zu analysieren.

Dies ist, um einige magische Schlüsselwörter in der CLI zu behandeln, was auch immer der Typ mit argparse definiert.

Bitte beachte, dass ich die folgende Frage im Zusammenhang lesen:

Handle invalid arguments with argparse in Python

und Python-Dokumentation, scheint keiner eine Antwort zu geben.

Antwort

1

Sie könnten eine Fehler fangen type Funktion definieren. Zum Beispiel wickelt int wie:

def trytype(astr, fn=int): 
    try: 
     ret = fn(astr) 
    except ValueError: 
     ret = ('error', astr) 
    return ret 

In [51]: parser = argparse.ArgumentParser() 
In [52]: parser.add_argument('-f', type=trytype); 
In [53]: parser.parse_args('-f 123'.split()) 
Out[53]: Namespace(f=123) 
In [54]: parser.parse_args('-f abc'.split()) 
Out[54]: Namespace(f=('error', 'abc')) 

Dies verallgemeinert werden könnte andere Art Funktionen zu handhaben (kann eine trytype Fabrik Funktion sein). Machen Sie auch alle Fehlertypen (ValueError, TypeError, ArgumentTypeError) abfangen. Und passen Sie den Rückgabewert an. Hier habe ich nur ein Tupel mit einer 'error'-Zeichenfolge und der ursprünglichen Zeichenfolge zurückgegeben.

In [55]: from functools import partial 
In [56]: partial(trytype, fn=float) 
Out[56]: functools.partial(<function trytype at 0xac13a8e4>, fn=<class 'float'>) 
In [57]: partial(trytype, fn=float)('12.34') 
Out[57]: 12.34 
In [58]: partial(trytype, fn=int)('12.34') 
Out[58]: ('error', '12.34') 
In [59]: partial(trytype, fn=str)('abc') 
Out[59]: 'abc' 

int in ein Argument akzeptieren und in einem anderen float:

In [60]: parser = argparse.ArgumentParser() 
In [61]: parser.add_argument('-i', type=partial(trytype, fn=int)); 
In [62]: parser.add_argument('-f', type=partial(trytype, fn=float)); 
In [63]: parser.parse_args('-f abc -i123'.split()) 
Out[63]: Namespace(f=('error', 'abc'), i=123) 
In [64]: parser.parse_args('-f 12.32 -ia23'.split()) 
Out[64]: Namespace(f=12.32, i=('error', 'a23')) 
In [65]: parser.parse_args('-f 12e32 -ia23'.split()) 
Out[65]: Namespace(f=1.2e+33, i=('error', 'a23')) 
In [66]: parser.parse_args('-f x2e32 -ia23'.split()) 
Out[66]: Namespace(f=('error', 'x2e32'), i=('error', 'a23')) 
+0

Dank, das ist eine nette Art und Weise! – dtrckd

Verwandte Themen