Python argparse解析未识别的参数

3
我有一个带有3-4个参数的解析器,它运行良好。我想向脚本提供未知数量的额外参数,这些参数将被加载到模板中。我已经阅读了argparse文档,但我不确定是否可能。我可以使用parse_known_arguments(),但我仍然必须自己处理["--placeholder1", "value1", "--placeholder2", "value2", ...]数组。我应该继续进行,还是有更pythonic的方法?
就我个人而言,我的建议如下:
parser = argparse.ArgumentParser()
parser.add_argument("--template", required=True)
parser.add_argument("--location", required=True)
args,unknown = parser.parse_known_arguments()
tpl = LoadTemplate(args.template)

# Missing part where I transform unknown into an dict or namespace called extraarguments
raw = tpl.render(extraarguments)

# Print into args.location raw
render.py --template template1 --location /path/to/invoices --author John --customer Customer1 --title "Your invoice is ready!"
render.py --template template2 --location /path/to/newsletter --customer Customer2 --sender john@store.com --subject "Weekly newsletter"

在这两种情况下,templatelocation都必须存在,但是额外的参数应该被解包并发送到模板渲染函数中。看起来好像只需要一行代码,但是是否有更多Pythonic的方法呢?


只是一些额外的参数,还是一堆未知选项和(可能)带有参数的选项?请给出一些您期望的命令行输入示例,以澄清您的问题。 - user707650
2
可能是argparse接受一切的重复问题。 - taleinat
如果您展示一下如何处理那个额外的列表,我们或许能够建议更好的方法。 - hpaulj
你能给我们一些argparse可以解析的命令参数的例子吗? - Vivian De Smedt
只需使用 docopt,它会让你微笑。 - bgusach
显示剩余2条评论
1个回答

6

假设unknown列表是一个交替出现的键和值的列表,则可以使用以下方法将其转换为字典:

adict = dict(zip(unknown[:-1:2],unknown[1::2]))

这个 zip 部分将列表转换为一对对的形式,然后再将其转换为字典。你可能需要对值进行更多处理,以删除键中的“--”前缀。如果需要检查错误(例如不匹配的“键值”序列),则可能需要更明确的迭代。

这里有一个版本保留了“--”:

templates = {'template1': "from: {--author} to: {--customer} re: {--title}",
             'template2': "from: {--sender} to: {--customer} re: {--subject}"}

def parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("--template", required=True, choices=templates)
    parser.add_argument("--location", required=True)
    args,unknown = parser.parse_known_args()
    extraarguments = dict(zip(unknown[::2], unknown[1::2]))
    tpl = templates[args.template]
    raw = tpl.format(**extraarguments)
    return raw
print parser()

使用您提供的两个样本,这将产生以下结果:
In [25]: run stack30139426.py --template template1 --location /path/to/invoices --author John --customer Customer1 --title "Your invoice is ready!"
from: John to: Customer1 re: Your invoice is ready!

In [26]: run stack30139426.py --template template2 --location /path/to/newsletter --customer Customer2 --sender john@store.com --subject "Weekly newsletter"
from: john@store.com to: Customer2 re: Weekly newsletter

关于输入字典或其他未知键 / 值对的问题,已经有其他SO问题。

一个建议是使用key:value语法,然后简单地使用[kv.split(':') for kv in unknowns]来生成一对列表:

run stack30139426.py --template template2 --location /path/to/newsletter customer:Customer2 sender:john@store.com subject:"Weekly newsletter"

另一种方法是使用JSON语法。
run stack30139426.py --template template2 --location /path/to/newsletter '{"customer":"Customer2", "sender":"john@store.com", "subject":"Weekly newsletter"}'

将一个JSON字符串附加到调用中似乎是一个更好的想法。 - user37203

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接