argparse 中的跨参数验证 [英] Cross-argument validation in argparse

查看:23
本文介绍了argparse 中的跨参数验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种 Pythonic 方法来验证参数,因为它们的验证在逻辑上取决于从其他参数解析的值.

I'm looking for a Pythonic way to validate arguments when their validation logically depends on the value(s) parsed from other argument(s).

这是一个简单的例子:

parser.add_argument(
    '--animal', 
    choices=['raccoon', 'giraffe', 'snake'], 
    default='raccoon',
)
parser.add_argument(
    '--with-shoes', 
    action='store_true',
)

在这种情况下,解析这个命令应该会导致错误:

In this case, parsing this command should cause an error:

my_script.py --animal snake --with-shoes

添加互斥组 似乎没有在这里提供帮助,因为其他组合都可以:

Adding a mutually exclusive group doesn't seem to help here, as the other combos are OK:

my_script.py --animal raccoon --with-shoes
my_script.py --animal raccoon
my_script.py --animal snake
my_script.py --animal giraffe --with-shoes
my_script.py --animal giraffe

理想情况下,验证错误不应与 --animal 参数或 --with-shoes 参数相关联,因为界面无法告诉您哪个 此处需要更改值.每个值都有效,但不能组合使用.

The validation error should ideally not be tied to --animal argument nor to --with-shoes argument, since the interface can not tell you which value needs to change here. Each value is valid, yet they can't be used in combination.

我们可以通过对 args 命名空间进行后处理来做到这一点,但我正在寻找一种会导致 parser.parse_args() 调用失败的解决方案,即我们实际上在解析参数解析失败,而不是之后.

We can do this with post-processing the args namespace, but I'm looking for a solution which would cause the parser.parse_args() call to fail, i.e. we actually fail during argument parsing, not afterwards.

推荐答案

解析后检查值是最简单的.您甚至可以使用 parser.error('...') 以标准 argparse 格式生成错误消息.

Checking values after parsing is simplest. You can even use parser.error('...') to produce an error message in the standard argparse format.

argparse 独立处理每个参数,并尝试以一种不关心顺序的方式来处理(除了 positionals).每个输入值都通过相应的 Action 对象(它的 __call__ 方法)添加到 args 命名空间中.默认的 store 操作只使用 setattr(args, dest, value);store_true 执行 setattr(args, dest, True).

argparse handles each argument independently, and tries to do so in a way that doesn't care about the order (except for positionals). Each input value is added to the args namespace by the corresponding Action object (its __call__ method). A default store action simply uses setattr(args, dest, value); a store_true does setattr(args, dest, True).

互斥组通过保留 seen_actionsset 并对照该组自己的操作列表进行检查来处理.我已经探索了对组进行概括以允许其他逻辑操作组合.尽管这已经变得很复杂(尤其是在显示 usage 时),但我并没有设想对值和出现情况进行测试.

Mutually exclusive groups are handled by keeping a set of seen_actions, and checking that against the group's own list of Actions. I've explored generalizing the groups to allow for other logical combinations of actions. As complicated as that has gotten (especially when displaying the usage), I didn't envisage testing for values as well as occurrence.

可以编写自定义的 Action 类来检查共现,但这会变得更加复杂.

It would be possible to write custom Action classes, that check for co-occurrence, but that gets more complicated.

我们可以给 with-shoes 一个 Action 类来检查 args.animal 属性的值,如果该值是 snake.但是如果用户首先提供 with-shoes 选项会怎样?我们必须给 animal 一个自定义类来检查 args.with_shoes 值,如果是 True 则引发错误,等等.所以shoes 必须了解animalsanimals 必须了解shoes.解析后测试允许您将逻辑放在一处.

We could give with-shoes an Action class that checks the values of the args.animal attribute, and raises an error if that value is snake. But what if the user provides the with-shoes option first? We'd have to give animal a custom class that checks the args.with_shoes value, and raise an error if that is True, etc. So shoes has to know about animals and animals has to know about shoes. Testing after parsing allows you to put the logic in one place.

使用像 argparse 这样的解析器的一大优势是它会为您生成用法、帮助和错误消息.但是像这样的验证逻辑很难自动表达.事实上,相对简单的互斥逻辑的用法格式很脆弱,很容易被破坏.

One of the big advantages to using a parser like argparse is it generates the usage, help, and error messages for you. But validation logic like this is hard to express automatically. As it is, the usage formatting for the relatively simple mutually-exclusive logic is brittle and easily broken.

之前尝试回答此类问题:

An earlier attempt at answering this kind of question:

Python 中的参数依赖项 - 无法使其工作

这篇关于argparse 中的跨参数验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆