处理Python ArgumentParser中的错误

时间:2016-08-30 15:57:11

标签: python python-2.7 python-3.x argparse

我想手动处理parse_args()在参数值未知的情况下抛出错误的情况。例如: 如果我有以下名为script.py的python文件:

argp = argparse.ArgumentParser(description='example')
argp.add_argument('--compiler', choices=['default', 'clang3.4', 'clang3.5'])
args = argp.parse_args()

我运行带有以下args python script.py --compiler=foo的脚本,它会抛出以下错误:

error: argument --compiler: invalid choice: 'foo' (choose from 'default', 'clang3.4', 'clang3.5')
SystemExit: 2

为了自己处理这种行为,我需要做什么而不是退出脚本?一个想法是继承argparse.ArgumentParser并覆盖parse_args()或只是修补方法,但我想知道是否有更好的方法不需要覆盖标准库行为?

1 个答案:

答案 0 :(得分:2)

定义选择的重点是让解析器抱怨列表中没有的值。但也有一些选择:

  • 省略选项(如果需要,请将它们包含在帮助文本中),并在解析后进行自己的测试。 argparse不必为您做任何事情。它的主要目的是找出用户想要的东西。

  • 重新定义parser.error方法(通过子类化最好)从sys.exit重定向错误。但是您必须解析错误消息以区分此错误与解析器可能引发的其他错误。

  • 定义一个检查选项的type函数,并进行默认替换。

解析' - 编译器'选项是这样的:

  • --compiler标志
  • 之后抓取字符串参数
  • 将其传递给type函数。默认值为lambda x:xint将其转换为整数等。提升ValueError值是不好的。
  • 根据choices列表(如果有)
  • 检查返回的值
  • 使用action将值添加到命名空间(默认只是存储它)。

任何这些步骤中的错误都会产生一个ArgumentError,它被parser.error方法捕获并传递给parser.exit方法。

由于在store_actiontype检查后发生choices,自定义操作不会绕过他们的错误。

这是一个可能的type解决方案(未经测试)

def compile_choices(astr):
   if astr in ['default', 'clang3.4', 'clang3.5']:
       return astr
   else:
       return 'default'
   # could raise ValueError('bad value') if there are some strings you don't like

argp.add_argument('--compiler', type=compile_choices)

=================

如果compile_choices采用其他参数,例如选项列表或默认值,那么您需要在解析之前包含一些定义这些值的原因。

接受二进制字符串表示的示例:

parser.add_argument('--binary', type=lambda x: int(x, base=2),
    help='integer in binary format', default='1010')

parser.add_argument('--binary', type=functools.partial(int, base=2), default='1010')