是否可以告诉
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
不一致,我现在认为上述行为是一个错误。以下确实会触发错误:
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
我为此打开了一个错误报告: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'])
不。显式参数需要验证,因为它们源自源代码“外部”。默认值源自源代码,因此确保它们有效是程序员的工作,而不是参数解析器的工作。 (这是验证和
调试之间的区别。)
(在未经验证的用户输入上使用 set_defaults
仍然属于调试范围,因为添加默认值的不是参数解析器本身,而是程序员。)
在验证来自 config.ini 文件的默认值的任务中,我努力镜像内部验证工作流程。它复制通过终端提供不正确的参数时观察到的行为和输出。
用途:
validate_args(program)