我正在编写一个程序,它应该接受多个文件作为输入,其中每个文件都给出了一个参数列表。调用可以是这样的:
python myprog.py
--file picture1.svg --scale 3 --color false
--file picture2.svg --scale 1 --color false
--file pictureX.svg --scale 11 --color true
-o output.svg
在我的例子中,文件的顺序和参数的正确分组当然都很重要。所以我希望最终能收到一个字典
[["file":"picture1.svg", "scale":3, "color":"false"],
["file":"picture2.svg", "scale":1, "color":"false"],
["file":"pictureX.svg", "scale":11, "color":"true"]]
---------------------------------------//------------------------------
目前我发现的是:
- 使用action ="append"使用argparse。
import argparse
parser = argparse.ArgumentParser(description='Call file list with parameters')
parser.add_argument('-f', '--file', type=str, nargs='+', action='append', help='file list')
parser.add_argument('-o', '--output', type=str, help='output file')
args = parser.parse_args()
print(args)
调用看起来像:
python myprog.py
--file picture1.svg scale:3 color:false
--file picture2.svg scale:1 color:false
--file pictureX.svg scale:11 color:true
-o output.svg
这将给我一个包含三个列表的列表,理论上我可以解析
[["picture1.svg", "scale:3", "color:false"],
["picture2.svg", "scale:1", "color:false"],
["picturex.svg", "scale:11", "color:true"]]
对于argparse的自动帮助生成来说,这不是最佳的工作方式,不允许声明默认值,等等。否则对我来说似乎是最优的解决方案
- 另一种方法是生成参数列表,如
parser.add_argument('-c', '--color', type=str, nargs='+', action='append', help='color list')
parser.add_argument('-s', '--scale', type=int, nargs='+', action='append', help='scale list')
可以这样调用:
python myprog.py
--file picture1.svg --scale 3 --color false
--file picture2.svg --scale 1 --color false
--file pictureX.svg --scale 11 --color true
-o output.svg
导致列表的列表:
[["picture1.svg", "picture2.svg", "picturex.svg"],
["scale:3", "scale:1", "scale:11"],
["color:false","color:false", "color:true"]]
优点是通过argparse处理一切。但是,如果缺少某些参数(例如第二个分数),则不能保证参数之间的对应关系。
- 我看到的最后一个可能性是使用json作为输入。它可以很容易地解析为我们想要的对象。但是,命令行解析器的所有优点将消失。
你认为最优的解决方案是什么,上面的一个,还是我忽略了什么,还有另一种优雅的方法?谢谢你!
嗯,我想我找到了一个方法,应该是通过argparse。
可以使用自己的数据类型作为命令行参数。参照上面的问题,我们可以创建一个类,类似于:
class Filetype():
patterns = {
'filename': re.compile(".*.svg"),
'scale': re.compile("scale:(d+.*d*)"),
'color': re.compile("color:(True|False)+"),
}
def __call__(self, value):
a = self.patterns["filename"].match(value)
if a:
return {"file": value}
a=self.patterns["scale"].match(value)
if a:
return {"scale": a.group(1)}
a=self.patterns["color"].match(value)
if a:
return {"color": a.group(1)}
raise argparse.ArgumentTypeError(
"'{}' should be either: (1) a file name (*.svg), (2) 'scale:FLOAT' parameter, or (3) 'code:[True|False]'".format(
value))
return value
现在,让我们向解析器添加一个参数。"type"参数执行工作
parser.add_argument('-f', '--file', type=Filetype(), nargs='+', action='append',
help='list of file names with parameters')
我们现在可以用:
python myprog.py
--file picture1.svg scale:3 color:false
--file picture2.svg scale:1 color:false
--file pictureX.svg scale:11 color:true
-o output.svg
这似乎是一个更好的妥协。虽然我们必须自己执行简单的检查,但仍然可以产生有意义的错误消息,argparse仍然为我们做繁重的工作