使参数解析器接受绝对数字和百分比的最佳方法?
Best way to make argument parser accept absolute number and percentage?
我正在尝试编写 Nagios 样式检查以与 Nagios 一起使用。我有一个工作脚本,它接收 -w 15 -c 10
之类的东西并将其解释为 "Warning at 15%, Critical at 10%"。但我刚刚意识到,在内置的 Nagios 插件中,相同的参数将意味着 "Warning at 15MB, Critical at 10MB";相反,我需要输入 -w 15% -c 10%
才能获得上述行为。
所以我的问题是,使我的脚本表现得像内置 Nagios 脚本的最佳方法是什么?我能想到的唯一方法是将参数作为字符串接受并解析它,但是有没有更简洁的方法?
您可以使用自己的 class 作为参数类型:
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
这是 type
函数,我认为它的行为与 @Mike's
相同 class:
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
必须是一个接受字符串的可调用对象,returns 是一个值。这里它返回一个元组,store
Action 只是将其放入 namespace
。如果可调用 returns 一个 ValueError、TypeError 或 argparse.ArgumentTypeError
,错误显示应该是相同的。在这些示例中,初始错误是由 float('bad')
产生的 ValueError。默认错误消息是使用可调用的名称 (Percent
v percent
).
post-parsing解析的一个例子是:
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.FileType
是 type
函数工厂 class 的示例。
我正在尝试编写 Nagios 样式检查以与 Nagios 一起使用。我有一个工作脚本,它接收 -w 15 -c 10
之类的东西并将其解释为 "Warning at 15%, Critical at 10%"。但我刚刚意识到,在内置的 Nagios 插件中,相同的参数将意味着 "Warning at 15MB, Critical at 10MB";相反,我需要输入 -w 15% -c 10%
才能获得上述行为。
所以我的问题是,使我的脚本表现得像内置 Nagios 脚本的最佳方法是什么?我能想到的唯一方法是将参数作为字符串接受并解析它,但是有没有更简洁的方法?
您可以使用自己的 class 作为参数类型:
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
这是 type
函数,我认为它的行为与 @Mike's
相同 class:
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
必须是一个接受字符串的可调用对象,returns 是一个值。这里它返回一个元组,store
Action 只是将其放入 namespace
。如果可调用 returns 一个 ValueError、TypeError 或 argparse.ArgumentTypeError
,错误显示应该是相同的。在这些示例中,初始错误是由 float('bad')
产生的 ValueError。默认错误消息是使用可调用的名称 (Percent
v percent
).
post-parsing解析的一个例子是:
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.FileType
是 type
函数工厂 class 的示例。