如何使用argparse要求我的python脚本的参数是0.0-1.0之间的浮点数?

Dol*_*cci 26 python range command-line-arguments argparse

我想argparse在Python 2.7 上使用我的脚本参数之一要求介于0.0和1.0之间.是否argparse.add_argument()支持呢?

che*_*ner 31

type参数add_argument只需要是一个可调用的对象,它接受一个字符串并返回一个转换后的值.您可以编写一个包装器float来检查其值,如果超出范围则会引发错误.

def restricted_float(x):
    try:
        x = float(x)
    except ValueError:
        raise argparse.ArgumentTypeError("%r not a floating-point literal" % (x,))

    if x < 0.0 or x > 1.0:
        raise argparse.ArgumentTypeError("%r not in range [0.0, 1.0]"%(x,))
    return x

p = argparse.ArgumentParser()
p.add_argument("--arg", type=restricted_float)
Run Code Online (Sandbox Code Playgroud)


And*_*ark 20

这是一个使用choices参数to 的方法,add_argument其自定义类被认为与指定范围内的任何浮点"相等":

import argparse

class Range(object):
    def __init__(self, start, end):
        self.start = start
        self.end = end
    def __eq__(self, other):
        return self.start <= other <= self.end

parser = argparse.ArgumentParser()
parser.add_argument('--foo', type=float, choices=[Range(0.0, 1.0)])
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个,因为它将异常提升到argparse.谢谢! (3认同)
  • 一个建议:让你的`Range`类实现`__contains__`方法; 然后你可以说`choices = Range(0.0,1.0)`而不是把它包装在一个列表中. (3认同)
  • 使用 Python 3.4 时,“__contains__”方法会给出“ValueError: length of metavar tuple does not match nargs”。否则它工作得很好,我实现了 `__repr__` 以返回 `'{0}-{1}'.format(self.start, self.end)` 以获得更漂亮的帮助文本。 (2认同)

小智 5

添加str使边界在帮助中可见。

import argparse

class Range(object):
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def __eq__(self, other):
        return self.start <= other <= self.end

    def __contains__(self, item):
        return self.__eq__(item)

    def __iter__(self):
        yield self

    def __str__(self):
        return '[{0},{1}]'.format(self.start, self.end)

parser = argparse.ArgumentParser()
parser.add_argument('--foo', type=float, choices=Range(0.0, 1.0))
parser.add_argument('--bar', type=float, choices=[Range(0.0, 1.0), Range(2.0,3.0)])
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,argparse 错误消息似乎显示了类的 repr,所以我只是将你的 `__str__` 方法更改为 `__repr__` 以获得一个不错的错误消息。 (2认同)