是否有可能告诉argparse
在默认参数值上给出与用户指定参数值相同的错误?
例如,以下命令不会产生任何错误:
parser = argparse.ArgumentParser()
parser.add_argument('--choice', choices=['a', 'b', 'c'], default='invalid')
args = vars(parser.parse_args()) # args = {'choice': 'invalid'}
而忽略默认值,让用户在命令行上指定--choice=invalid
将导致错误(如预期的那样)。
询问的原因是,我希望用户能够在JSON文件中指定默认的命令行选项,然后使用ArgumentParser.set_defaults()
设置,但不幸的是,上面演示的行为阻止了这些用户指定的默认值被验证。
更新:argparse
不一致,我现在认为上面的行为是一个bug。
parser = argparse.ArgumentParser()
parser.add_argument('--num', type=int, default='foo')
args = parser.parse_args() # triggers exception in case --num is not
# specified on the command-line
我已经打开了一个bug报告:https://github.com/python/cpython/issues/100949
我花时间深入研究了源代码,结果发现只对您在命令行中给出的参数进行检查。在我看来,强制检查的唯一方法是创建ArgumentParser的子类,并在添加参数时让它执行检查:
class ValidatingArgumentParser(argparse.ArgumentParser):
def add_argument(self, *args, **kwargs):
super().add_argument(*args, **kwargs)
self._check_value(self._actions[-1],kwargs['default'])
No。需要验证显式参数,因为它们来自源代码之外的。默认值起源于源代码中的,因此确保它们有效是程序员的工作,而不是参数解析器的工作。
(这是验证和调试之间的区别)
(在未经验证的用户输入上使用set_defaults
仍然属于调试范围,因为不是参数解析器本身添加默认值,而是程序员添加的。)