我有一个包含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"
在这两种情况下,template
和location
都必须存在,但是应该解压缩额外的参数并将其发送到模板渲染函数中。它看起来像一个单行,但有更多的pythonic方式吗?
答案 0 :(得分: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()
用你的2个样本产生:
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"}'