从python中的命令行使用参数解析多个列表

Posted

技术标签:

【中文标题】从python中的命令行使用参数解析多个列表【英文标题】:Parsing multiple lists with parameters from the command line in python 【发布时间】:2021-12-07 11:36:56 【问题描述】:

我正在编写一个程序,它应该将多个文件作为输入,其中为每个文件提供一个参数列表。调用可能如下所示:

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"]]

---------------------------------------------------//------ ------------------------------------

到目前为止我发现的是:

    通过 argparse 使用 action="append"。
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 作为输入。它可以很容易地解析成我们想要的对象。但是,命令行解析器的所有优势都将消失。

您认为最佳解决方案是上述中的一个,还是我忽略了某些事情而有另一种优雅的方法可以做到这一点? 谢谢!

【问题讨论】:

【参考方案1】:

好吧,我想我找到了一种应该是 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

现在,让我们为解析器添加一个参数。 “类型”参数完成工作

 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 仍然为我们完成繁重的工作

【讨论】:

以上是关于从python中的命令行使用参数解析多个列表的主要内容,如果未能解决你的问题,请参考以下文章

Python笔记:命令行参数解析

从命令行传递参数作为列表并解析它

python中的argparse包——用于解析命令行参数

使用多个参数解析命令行选项 [getopt?]

从for循环中的列表中解压缩多个参数

27.Go 解析命令行参数