python:argparse中奇怪的错误行为
当组合标志(python:argparse中奇怪的错误行为,python,argparse,Python,Argparse,当组合标志(-x-y-xy)时,argparse给了我不同的结果。很难用语言解释,因此我将问题简化为以下最小设置: # test.py def invalid_argument_type(x): raise Exception("can't parse this") # in my code, it doesn't *always* fail parser = argparse.ArgumentParser() parser.add_argument('args', type = i
-x-y
-xy
)时,argparse
给了我不同的结果。很难用语言解释,因此我将问题简化为以下最小设置:
# test.py
def invalid_argument_type(x):
raise Exception("can't parse this") # in my code, it doesn't *always* fail
parser = argparse.ArgumentParser()
parser.add_argument('args', type = invalid_argument_type)
parser.add_argument('-x')
print parser.parse_args()
现在,错误地调用这个程序会产生意想不到的结果。第一个命令正确,第二个命令具有无效标志,第三个命令应与第二个命令相同:
$ python test.py -x foo
Namespace(args=[], x='foo')
$ python test.py -A -x foo
test.py: error: unrecognized arguments: -A
$ python test.py -Ax foo
Exception: can't parse this
似乎在组合这些标志时,“未知标志”错误会吞没-x
,而foo
被视为常规参数。请注意,如果存在-A
标志,则-A
和-x
在每个场景中都会按预期工作
这会导致非常混乱的错误消息
我是否使用了
argparse
错误?有没有办法解决这个问题,或者我应该自己处理错误?您看到了这一点,因为在参数解析过程中发生的异常比简单的参数错误更重要。参数解析确实识别出-Ax
是一个无效的标志,并简单地记录该标志,以便以后显示;但是由于解析args
失败并出现异常,因此会立即显示该异常,并且不再提及其他无效参数
您还可以从源代码中确认此行为。将解析步骤委托给parse_known_args
,返回解析后的名称空间和无效参数列表。但是,将在内部尝试解析它,如果出现异常,将立即显示它。因此,异常将在parse_args
显示无效参数之前中止该过程
现在,您的三个示例的工作方式都不同,这就是为什么您只看到最后一个示例的例外。让我们详细检查一下:
:这里,-xfoo
是一个有效的参数名,-x
是该参数的值。所以一切都很好foo
:-A-xfoo
是一个无法识别的参数,因此已记下。剩下的部分是-A
,这也是参数-xfoo
的有效序列x
:-Ax foo
是一个无法识别的参数,因此再次记下。剩下的部分是-Ax
。由于没有参数标志,解析器将尝试将其与foo
参数匹配,然后引发异常args
请注意,如果argparse能够从左到右正确解析组合标志(
-Ax
),那么它只支持组合标志。由于单破折号标志也可以长于一个字符(例如,-foo
就可以了),因此不能安全地说-Ax
将是-A-x
,因为您可以实际定义一个-Ax
参数。为了能够做出这条语句,它实际上将开始解析-Ax
,首先尝试找到与之匹配的参数。由于没有-A
参数,它假定它应该是-Ax
。但这也不存在,因此它在那里失败。但是当标志有效时,组合标志似乎可以正常工作:(是的,你说得对。我的答案更新了一点。基本上,它不能开始将-Ax
与任何已知参数匹配,因此它不知道在哪里将其分开。因此,它根本不这样做,并将整个-Ax
标记为无效。我将减少argparse
的责任,稍后再做我自己的错误处理。)如果命令行参数中存在多个错误,argparse
不会承诺首先捕获哪一个错误。您必须研究代码内部结构才能猜到这一点。之后进行自己的错误检查没有错。