2013-02-06 8 views
31

Nie sądzę, że jest to możliwe, ale chcę obsługiwać wyjątki od argparse siebie.Chcę Python argparse rzucić wyjątek, a nie użycie

Na przykład:

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

Kiedy uruchamiam go:

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

Ale chcę wpaść wyjątkiem zamiast.

+2

Nie używasz argparse do tego, do czego został zaprojektowany. Co chcesz robić? –

+9

Nie jest źle zmienić sposób, w jaki działa wspaniała biblioteka, tylko po to, aby dostroić ją do konkretnego projektu. – jdborg

+4

Właściwie możesz to już zrobić. po prostu złap 'SystemExit' i zamień' sys.stderr' na jakiś inny obiekt. – Bakuriu

Odpowiedz

55

Można podklasy ArgumentParser i zastąpić metodę error zrobić coś innego, gdy wystąpi błąd:

class ArgumentParserError(Exception): pass 

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

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

Myślałem, że to będzie coś takiego. Dzięki za jasną odpowiedź. – jdborg

+3

Miałem nadzieję, że uniknę czegoś takiego, choć cieszę się, że to opcja. Widzisz, próbuję wydrukować menu pomocy, gdy otrzymuję powiadomienie "błąd: zbyt mało argumentów"; moja konfiguracja argparse wymaga co najmniej jednego argumentu, aby pomyślnie uruchomić, ale sądzę, że byłoby grzecznie wydrukować, jakie są te polecenia, bez konieczności uruchamiania skryptu za pomocą parametru "-h". Coś jak: 'parser.set_error ('zbyt mało argumentów', method_to_deal_with_error)' Przypuszczam, że zawsze mogę zgłosić błąd, jeśli chcę tę funkcję. Dzięki! – NuclearPeon

12

w moim przypadku, argparse drukuje „zbyt mało argumentów”, a następnie zamknąć. po przeczytaniu kodu argparse, znalazłem, że po prostu wywołuje sys.exit() po wydrukowaniu jakiegoś komunikatu. ponieważ sys.exit() nie robi nic poza zgłoszeniem wyjątku SystemExit, możesz po prostu uchwycić ten wyjątek.

spróbuj więc sprawdzić, czy to działa.

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

Tak, ta opcja jest wymieniona powyżej w komentarzu Bakuriu. Unittesting 'test_argparse.py' używa tego podejścia, wraz z przedefiniowaniem' error', aby utworzyć klasę 'ErrorRaisingArgumentParser'. – hpaulj

+3

komunikat o błędzie jest wyrzucany na stderr. Czy istnieje sposób, aby to złapać? – Raj

+1

@Raj Możesz tymczasowo przekierować stderr do innego obiektu strumienia/pliku, na przykład: https://stackoverflow.com/a/6796752/2128769 – umi

Powiązane problemy