Python语法分析器中的错误处理
我想手动处理Python语法分析器中的错误处理,python,python-2.7,python-3.x,argparse,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() 我使用以下参数运行脚本python script.py-
parse_args()
在参数值未知时抛出错误的情况。例如:
如果我有以下名为script.py
的python文件:
argp = argparse.ArgumentParser(description='example')
argp.add_argument('--compiler', choices=['default', 'clang3.4', 'clang3.5'])
args = argp.parse_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()
或只是对该方法进行修补,但我想知道是否有更好的方法不需要重写标准库行为?定义选择的关键是让解析器抱怨列表中没有的值。但也有一些替代方案:
- 省略选项(如果需要,请将其包含在帮助文本中),并在解析后执行您自己的测试
不必为您做任何事情。它的主要目的是找出你的用户想要什么argparse
- 重新定义
方法(最好通过子类化)以重定向parser.error
中的错误。但您必须解析错误消息,以区分此错误和解析器可能引发的其他错误sys.exit
- 定义一个检查选项的
函数,并进行默认替换类型
- 获取
标志后的字符串参数--compiler
- 通过
功能传递它。默认值为类型
lambda x:x
将其转换为整数等。Raiseint
是值错误ValueError
- 对照
列表(如果有)检查返回值选项
- 使用
将值添加到名称空间(默认值仅存储该值)操作
ArgumentError
,它被解析器.Error
方法捕获并传递给解析器.exit
方法
由于store\u操作
发生在类型
和选项
检查之后,因此自定义操作不会绕过它们的错误
这里有一个可能的类型
解决方案(未测试)
=================
如果compile\u choices
采用其他参数,如选项列表或默认值,则需要在解析之前总结定义这些值的原因
接受二进制字符串表示的示例:
parser.add_argument('--binary', type=lambda x: int(x, base=2),
help='integer in binary format', default='1010')
或
您想如何处理选项列表中的不同选项?@M.Klugerford不重要,但为了简化,如果某个标志与不在选项列表中的编译器值一起传递,我想说的是,应该假设
clang3.4
作为参数来运行scrip。创建一个定制怎么样?@FamousJameous这看起来很有希望。我们将对此进行调查并在此处更新。你有好的例子可供参考吗?@Siddharth,完全公开,我从未在argparse
中编写过自定义操作。我在optparse
中也做过类似的事情,只是从来没有argparse
。这里有一个问题:这可能会有所帮助。如果我想传递另一个参数来编译_选项以及编译器值,该怎么办?在将参数传递给解析器之前,使用lambda
或partial
或包装函数来提供这些参数。我加了一个例子。
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')