我如何使用argparse
指定浮点数参数的最小值或最大值?我希望能够在最小值和最大值之间提供命令行参数。
我能找到的最接近的选项是add_argument()
中的choices
选项,但这只指定了参数的可允许值。
parser.add_argument("L", type=float, choices=range(2))
命令行参数0.5
无法满足L的要求:invalid choice: 0.5 (choose from 0, 1)
你可以(而且应该)使用自定义类型函数。这样更加用户友好。
def range_limited_float_type(arg):
""" Type function for argparse - a float within some predefined bounds """
try:
f = float(arg)
except ValueError:
raise argparse.ArgumentTypeError("Must be a floating point number")
if f < MIN_VAL or f > MAX_VAL:
raise argparse.ArgumentTypeError("Argument must be < " + str(MAX_VAL) + "and > " + str(MIN_VAL))
return f
parser.add_argument(
'-f',
'--float',
type=range_limited_float_type,
help='Your argument description'
)
基于@rdas的精彩解决方案,我创建了一个新的解决方案,允许动态指定应该由ArgumentParser检查的浮点范围。
import argparse
def float_range(mini,maxi):
"""Return function handle of an argument type function for
ArgumentParser checking a float range: mini <= arg <= maxi
mini - minimum acceptable argument
maxi - maximum acceptable argument"""
# Define the function with default arguments
def float_range_checker(arg):
"""New Type function for argparse - a float within predefined range."""
try:
f = float(arg)
except ValueError:
raise argparse.ArgumentTypeError("must be a floating point number")
if f < mini or f > maxi:
raise argparse.ArgumentTypeError("must be in range [" + str(mini) + " .. " + str(maxi)+"]")
return f
# Return function handle to checking function
return float_range_checker
您可以在ArgumentParser中将此函数用作动态参数类型生成器:
parser = ArgumentParser(description='%(prog)s: My programm')
parser.add_argument('--Temperature', type=float_range(8,25),
help='Set target temperature between [8°C .. 25°C].')
float_range(mini,maxi)
函数创建一个本地上下文环境,其中mini
和maxi
是已知的变量。在此上下文中定义float_range_checker()
函数并返回其句柄。当ArgumentParser
调用此函数句柄时,将还原使用float_range()
调用时提供的值的上下文,并进行范围检查。
受到已有答案的启发,这里提供一个更通用的解决方案,适用于从字符串输入创建的所有类型,并带有工作的"<"和">"运算符:
def ranged_type(value_type, min_value, max_value):
"""
Return function handle of an argument type function for ArgumentParser checking a range:
min_value <= arg <= max_value
Parameters
----------
value_type - value-type to convert arg to
min_value - minimum acceptable argument
max_value - maximum acceptable argument
Returns
-------
function handle of an argument type function for ArgumentParser
Usage
-----
ranged_type(float, 0.0, 1.0)
"""
def range_checker(arg: str):
try:
f = value_type(arg)
except ValueError:
raise argparse.ArgumentTypeError(f'must be a valid {value_type}')
if f < min_value or f > max_value:
raise argparse.ArgumentTypeError(f'must be within [{min_value}, {min_value}]')
return f
# Return function handle to checking function
return range_checker
您可以将其用于浮点数和整数,但不仅限于此:
parser.add_argument('--float_example',
type=ranged_type(float, 0.0, 1.0))
parser.add_argument('--int_example',
type=ranged_type(int, -5, 5))
甚至可以与字符串一起使用
parser.add_argument('--str_example',
type=ranged_type(str, "a", "d"))
一个小型测试/概念验证:
parser = argparse.ArgumentParser(prog='argtest')
parser.add_argument('--float_example',
type=ranged_type(float, 0.0, 1.0))
parser.add_argument('--int_example',
type=ranged_type(int, -5, 5))
parser.add_argument('--str_example',
type=ranged_type(str, "a", "d"))
print(parser.parse_args())
以下是相应的结果:
> python argtest.py --float_example 0.5 --str_example b --int_example 4
Namespace(float_example=0.5, int_example=4, str_example='b')
> python argtest.py --float_example -0.5
usage: argtest [-h] [--float_example FLOAT_EXAMPLE] [--int_example INT_EXAMPLE] [--str_example STR_EXAMPLE]
argtest: error: argument --float_example: must be within [0.0, 1.0]
> python argtest.py --int_example 12
usage: argtest [-h] [--float_example FLOAT_EXAMPLE] [--int_example INT_EXAMPLE] [--str_example STR_EXAMPLE]
argtest: error: argument --int_example: must be within [-5, 5]
> python argtest.py --str_example g
usage: argtest [-h] [--float_example FLOAT_EXAMPLE] [--int_example INT_EXAMPLE] [--str_example STR_EXAMPLE]
argtest: error: argument --str_example: must be within [a, d]
argparse
之外处理命令行输入的最小或最大值的验证。这样可以编写一个函数和条件来检查浮点值。如果条件得到满足,则退出程序:import sys
# function to print error to stderr
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs
# input validation
if args.L <=0:
eprint("Input error. Length is less than 0. Please enter a positive length. Exiting.")
sys.exit(1)
type
函数。 - hpaulj