Python argparse类型和选择限制与nargs> 1

时间:2011-12-24 10:46:45

标签: python argparse

标题几乎说明了一切。如果我有大于1的nargs,有什么方法可以在解析的各个args上设置限制(例如选择/类型)吗?

这是一些示例代码:

parser = argparse.ArgumentParser()
parser.add_argument('-c', '--credits', nargs=2,
    help='number of credits required for a subject')

对于-c参数,我需要指定一个主题以及需要多少学分。主题应限于预定义的主题列表,所需的学分数应为浮点数。

我可以用subparser做到这一点,但因为它已经是子命令的一部分所以我真的不想让事情变得更复杂。

4 个答案:

答案 0 :(得分:19)

您可以使用custom action:

对其进行验证
import argparse
import collections


class ValidateCredits(argparse.Action):
    def __call__(self, parser, args, values, option_string=None):
        # print '{n} {v} {o}'.format(n=args, v=values, o=option_string)
        valid_subjects = ('foo', 'bar')
        subject, credits = values
        if subject not in valid_subjects:
            raise ValueError('invalid subject {s!r}'.format(s=subject))
        credits = float(credits)
        Credits = collections.namedtuple('Credits', 'subject required')
        setattr(args, self.dest, Credits(subject, credits))

parser = argparse.ArgumentParser()
parser.add_argument('-c', '--credits', nargs=2, action=ValidateCredits,
                    help='subject followed by number of credits required',
                    metavar=('SUBJECT', 'CREDITS')
                    )
args = parser.parse_args()
print(args)
print(args.credits.subject)
print(args.credits.required)

例如,

% test.py -c foo 2
Namespace(credits=Credits(subject='foo', required=2.0))
foo
2.0
% test.py -c baz 2
ValueError: invalid subject 'baz'
% test.py -c foo bar
ValueError: could not convert string to float: bar

答案 1 :(得分:3)

旁注,因为在搜索“ argparse nargs选择”时会出现此问题:

仅当nargs参数需要异类验证时才需要自定义操作,即索引0处的参数应与索引1处的参数(此处:float)使用不同的类型(此处为受限制的主题类型)等

如果需要同种类型验证,则直接将nargschoices组合就足够了。例如:

parser.add_argument(
    "--list-of-xs-or-ys",
    nargs="*",
    choices=["x", "y"],
)

将允许使用--list-of-xs-or-ys x y x y之类的内容,但是如果用户指定了xy之后的其他内容,则会提出投诉。

答案 2 :(得分:0)

Action类的调用者仅捕获ArgumentError。

https://github.com/python/cpython/blob/3.8/Lib/argparse.py#L1805

如果希望由调用者捕获异常,则应在自定义操作中提出以下要求。

raise ArgumentError(self, 'invalid subject {s!r}'.format(s=subject))

答案 3 :(得分:-3)

我想您可以尝试这一点 - 在add_argument()中,您可以使用choice ='xyz'或choice = [this,that]指定一组有限的输入 如下所述: http://docs.python.org/library/argparse.html#choices

parser = argparse.ArgumentParser()
parser.add_argument('-c', '--credits', choice='abcde', nargs=2, 
    help='number of credits required for a subject')