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

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

问题描述

当逻辑上的验证取决于从其他参数解析的值时,我正在寻找一种Python方式来验证参数.

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_truesetattr(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).

相互排斥的组通过保持setseen_actions并对照该组自己的动作"列表进行检查来进行处理.我已经探索了对各组进行一般化以允许其他逻辑组合的动作.尽管已经变得如此复杂了(尤其是在显示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必须了解animals,而animals了解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天全站免登陆