【问题标题】:Python argparse parse unrecognised argumentsPython argparse 解析无法识别的参数
【发布时间】:2015-07-20 06:58:00
【问题描述】:

我有一个带有 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 的方式呢?

【问题讨论】:

  • 只是简单的额外参数,还是一堆带有(可能)参数的未知选项?提供一些您期望的命令行输入示例,以澄清您的问题。
  • argparse accept everything 的可能重复项
  • 如果您说明您将如何处理额外的列表,我们可能会提出更好的方法。
  • 你能给我们一些命令参数的例子吗?argparse parse?
  • 我已经更新了问题。

标签: python python-2.7 argparse


【解决方案1】:

假设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"}'

【讨论】:

  • 在调用中附加一个 JSON 字符串似乎是一个更好的主意。
猜你喜欢
  • 2013-06-11
  • 1970-01-01
  • 2019-07-14
  • 2012-09-30
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多