【问题标题】:Python argparse type and choice restrictions with nargs > 1Python argparse 类型和选择限制与 nargs > 1
【发布时间】:2012-01-27 06:49:41
【问题描述】:

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

这是一些示例代码:

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

对于 -c 参数,我需要指定一个主题以及需要多少学分。该科目应限制在预定义的科目列表中,并且所需的学分数量应该是浮动的。

我可能可以使用子解析器来执行此操作,但因为它已经是子命令的一部分,所以我真的不希望事情变得更复杂。

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    您可以使用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
    

    【讨论】:

    • 终于开始实施这个了,伙计,你的解决方案很好。希望我能给你更多的赞成票!谢谢!
    • 后人注意:将metavar=("SUBJECT", "CREDITS") 添加到add_argument 调用将使帮助显示--credits SUBJECT CREDITS 而不是--credits CREDITS CREDITS
    【解决方案2】:

    旁注,因为在搜索“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 以外的任何内容,则会抱怨。

    【讨论】:

      【解决方案3】:

      Action 类的调用者只捕获 ArgumentError。

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

      为了期望调用者捕获异常,您应该在您的自定义操作中引发如下。

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

      【讨论】:

        【解决方案4】:

        我想你可以试试这个 - 在 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')
        

        【讨论】:

        • 这将为每个参数设置相同的选择。这不是问题中要求的。
        猜你喜欢
        • 2018-06-29
        • 2014-10-11
        • 2021-11-11
        • 2017-06-04
        • 2022-08-19
        • 2017-08-20
        • 2016-11-01
        • 1970-01-01
        • 2015-03-03
        相关资源
        最近更新 更多