Python argparse 解析无法识别的参数

问题描述 投票:0回答:2

我有一个带有 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 [email protected] --subject "Weekly newsletter"

在这两种情况下,

template
location
都必须存在,但额外的参数应该被解包并发送到模板渲染函数中。它看起来像一句简单的话,但是有没有一种更Pythonic的方法来做到这一点?

python python-2.7 argparse
2个回答
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 [email protected] --subject "Weekly newsletter"
from: [email protected] to: Customer2 re: Weekly newsletter

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

一个建议是使用

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

run stack30139426.py --template template2 --location /path/to/newsletter customer:Customer2 sender:[email protected] subject:"Weekly newsletter"

另一种是使用 JSON 语法

run stack30139426.py --template template2 --location /path/to/newsletter '{"customer":"Customer2", "sender":"[email protected]", "subject":"Weekly newsletter"}'

0
投票

部分自动化该过程的一种方法可以是通过使用

argparse
中以 '--' 开头的字符串作为参数名称创建另一个解析器来重用
unknown

argument_names = [arg for arg in unknown if arg[:2] == '--']
parser = argparse.ArgumentParser()
for arg in argument_names:
    parser.add_argument(arg)
args = parser.parse_args(unknown)

但是,如果提供了名称-值对之外的任何内容,这将会失败。

© www.soinside.com 2019 - 2024. All rights reserved.