使用argparse对默认参数进行自定义类型或动作
我想把传给argparse的参数转换成另一种格式;我的想法是传一个数字(通常是浮点数),然后把它转换成字符串(通常是浮点数的Fortran表示法)。
首先,我尝试创建一个自定义类型。
def FortranFloat(value):
vfloat = float(value)
vfloat = str(vfloat) + "d0"
return vfloat
parser = argparse.ArgumentParser()
parser.add_argument("--xmin=", dest="xmin", type=FortranFloat, default=-2.0)
args = parser.parse_args()
这方法很好用……前提是我真的给了--xmin=
这个参数。如果没有,它就会保持-2.0
不变,而没有按照我想要的方式转换成-2.0d0
。所以我想,给默认值用我想要的格式可能更简单,就把2.0
换成'2.0d0'
……有趣的是,这样做会出问题,因为它崩溃并抛出以下错误:
argparse.ArgumentError: argument --xmin=: invalid FortranFloat value: '-2.0d0'
为了绕过这个问题,我尝试创建一个自定义动作。
class FortranConverter(argparse.Action):
def __call__(self, parser, namespace, values, option_strings=None):
if type(values) is float:
values = str(values) + "d0"
setattr(args, self.dest, values)
parser = argparse.ArgumentParser()
parser.add_argument("--xmin=", dest="xmin", type=float, default=-2.0, action=FortranConverter)
args = parser.parse_args()
但这也没成功。似乎根本没有经过我的动作(如果我在__call__
里打印东西,它会直接忽略掉)。
任何想法、主意或解释都非常感谢!
1 个回答
8
如果default
是一个字符串,它会被传递给type
函数处理。其他类型的值则直接使用:setattr(namespace, dest, default)
。你试过'-2.0'吗?你的FortranFloat
应该能把它转换成'-2.0d0'。
另一个选择是修改你的FortranFloat
,让它能识别带有'd0'的字符串,并且不做任何改变地传递它。
在将参数字符串传递给action
之前,会先通过type
处理。如果我没记错的话,default
是不会经过action
的,它是直接设置的。
你不一定需要这样做,但为了能正常工作,你的FortranConverter
函数应该使用setattr(namespace, self.dest, values)
。
你想用nargs=0
达到什么目的?像'store_true'这样的操作会用它来表示它们不接受任何参数。否则,这对程序员来说就没有什么用处。