2017-02-15 10 views
0

Возможно ли уловить ошибку, возникшую при неправильном типе значения с помощью argparse (недопустимое значение, но аргумент распознается), чтобы узнать, что вызвало ошибку и в конечном итоге игнорировать (продолжить с разбора)?Как поймать значение, которое вызывает ошибку argparse в Python

Я знаю, что могу переопределить метод ошибки ArgumentParser, но он дает только сообщение об ошибке в виде строки, и я бы хотел избежать разбора этой строки.

Это предназначено для обработки некоторых магических ключевых слов в CLI независимо от типа, определенного с помощью argparse.

Обратите внимание, что я прочитал следующий связанный с этим вопрос:

Handle invalid arguments with argparse in Python

и документация Python, ни один, кажется, дает ответ.

ответ

1

Вы можете определить ошибку, уловив ошибку type. Например обернуть int как:

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')) 

Это может быть обобщена для обработки других функций типа (может быть функцией завода trytype). Также заставьте его уловить все типы ошибок (ValueError, TypeError, ArgumentTypeError). И настройте возвращаемое значение. Здесь я просто вернул кортеж со строкой «error» и исходной строкой.

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 [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

Спасибо, что это хороший способ! – dtrckd