使参数解析器接受绝对数和百分比的最佳方法是什么?

时间:2017-01-19 11:48:10

标签: python argparse nagios

我正在尝试编写与Nagios一起使用的Nagios样式检查。我有一个工作脚本,其中包含-w 15 -c 10之类的内容,并将其解释为“警告为15%,严重为10%”。但我刚刚意识到,在内置的Nagios插件中,相同的参数意味着“警告15MB,严重10MB”;我需要输入-w 15% -c 10%来获得上述行为。

所以我的问题是,让我的脚本像内置的Nagios脚本一样运行的最佳方法是什么?我能想到的唯一方法是将参数作为字符串接受并解析它,但是有更简洁的方法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用自己的类作为参数的类型:

import argparse

class Percent(object):
    def __new__(self,  percent_string):
        if not percent_string.endswith('%'):
            raise ValueError('Need percent got {}'.format(percent_string))
        value = float(percent_string[:-1]) * 0.01
        return value

parser = argparse.ArgumentParser(description="with percent")
parser.add_argument('-w', '--warning', type=Percent)
parser.add_argument('-c', '--critcal', type=Percent)

args = parser.parse_args()
print(args.warning)

输出:

python parse_percent.py  -w 15%
0.15

python parse_percent.py  -w 15
usage: parse-percent.py [-h] [-w WARNING] [-c CRITCAL]
parse-percent.py: error: argument -w/--warning: invalid Percent value: '15'

使用百分比或MB

的版本
class Percent(object):
    def __new__(self,  percent_string):
        if percent_string.endswith('%'):
            return float(percent_string[:-1]), 'percent'
        else:
            return float(percent_string), 'MB'

parser = argparse.ArgumentParser(description="with percent")
parser.add_argument('-w', '--warning', type=Percent)
parser.add_argument('-c', '--critcal', type=Percent)

args = parser.parse_args()
value, unit = args.warning
print('{} {}'.format(value, unit))

输出:

python parse_percent.py -w 15
15.0 MB
python parse_percent.py -w 15%
15.0 percent

答案 1 :(得分:1)

这是type函数,我认为它与@Mike's类的行为相同:

def percent(astr):
    if astr.endswith('%'):
        return float(astr[:-1]), 'percent'
    else:    
        return float(astr), 'MB'

parser = argparse.ArgumentParser(description="with percent")
parser.add_argument('-w', '--warning', type=Percent)
parser.add_argument('-c', '--critcal', type=percent)

args = parser.parse_args()
print(args)

测试:

1058:~/mypy$ python3 stack41741065.py 
Namespace(critcal=None, warning=None)

1059:~/mypy$ python3 stack41741065.py -w 14 -c 14
Namespace(critcal=(14.0, 'MB'), warning=(14.0, 'MB'))

1059:~/mypy$ python3 stack41741065.py -w 14% -c 14%
Namespace(critcal=(14.0, 'percent'), warning=(14.0, 'percent'))

1059:~/mypy$ python3 stack41741065.py -w bad
usage: stack41741065.py [-h] [-w WARNING] [-c CRITCAL]
stack41741065.py: error: argument -w/--warning: invalid Percent value: 'bad'

1100:~/mypy$ python3 stack41741065.py -c bad
usage: stack41741065.py [-h] [-w WARNING] [-c CRITCAL]
stack41741065.py: error: argument -c/--critcal: invalid percent value: 'bad'

type只需要是一个可调用的字符串,然后返回一个值。这里返回一个元组,store Action只放入namespace。如果callable返回ValueError,TypeError或argparse.ArgumentTypeError,则错误显示应该相同。在这些示例中,初始错误是float('bad')生成的ValueError。默认错误消息使用可调用名称(Percent v percent)。

解析后解析的一个例子是:

if args.o is not None:
    try:
        args.o = percent(args.o)
    except ValueError:
        parser.error('invalid args.o value')
print(args)

100:~/mypy$ python3 stack41741065.py
Namespace(critcal=None, o=None, warning=None)
Namespace(critcal=None, o=None, warning=None)

1107:~/mypy$ python3 stack41741065.py -o 14
Namespace(critcal=None, o='14', warning=None)
Namespace(critcal=None, o=(14.0, 'MB'), warning=None)

1107:~/mypy$ python3 stack41741065.py -o 14%
Namespace(critcal=None, o='14%', warning=None)
Namespace(critcal=None, o=(14.0, 'percent'), warning=None)

1107:~/mypy$ python3 stack41741065.py -o bad
Namespace(critcal=None, o='bad', warning=None)
usage: stack41741065.py [-h] [-w WARNING] [-c CRITCAL] [-o O]
stack41741065.py: error: invalid args.o value

argparse.FileTypetype函数工厂类的示例。