【问题标题】:Parse non-pre-defined argument解析非预定义参数
【发布时间】:2014-02-20 22:22:02
【问题描述】:

是否有任何库可以在 Python 中解析 sys.argv 中的随机键值对?

例如:

 python run.py --v1 k1 --v2 k2 --v3 k3

应该给我一个像 {v1->k1, v2->k2, v3->k3} 这样的字典。在编译时我不知道那些'v'会是什么。

谢谢!

二本

【问题讨论】:

  • 你将如何使用你事先不知道名字的选项?
  • 我建议改用--var v1=k1 --var v2=k2 --var v3=k3 之类的东西
  • 用python制作一个工具,它接受一个模板文件和一堆k-v对。类似于 jinja2

标签: python argparse


【解决方案1】:

这有点老套,但你确实有这个:

import argparse
import collections
parser = argparse.ArgumentParser()
known, unknown_args = parser.parse_known_args()

unknown_options = collections.defaultdict(list)
key = None
for arg in unknown_args:
    if arg.startswith('--'):
        key = arg[2:]
    else:
        unknown_options[key].append(arg)

【讨论】:

  • 所以基本上这个解决方案让提问者从他开始的地方开始——需要一个库来解析一个意外选项列表。此外,它还可以轻松优化到 unknown_args = sys.argv,因为它实际上就是这样做的。
  • 哦,你是对的,这真是太垃圾了。我现在添加了更多代码。
  • btw sys.argv 中还有其他内容,例如脚本名称
  • 仍然不完美,因为我们必须在 unknown_args 中手动搜索“--”。但是 parse_known_args 解决的一个问题是它返回 unknown_args 而不管顺序如何。即您可以拥有 --known_k1 v1 --unknown_k2 v2 --known_k3 v2 它将过滤掉已知的参数
  • argparsesys.argv[1:] 开头。如果没有其他参数需要处理,您可以跳过argparse 部分。
【解决方案2】:
d = {}
for i,arg in enumerate(sys.argv):
    if arg.startswith("--"):
        d[arg[2:]] = sys.argv[i+1]

print d

【讨论】:

  • 对于中间没有值的连续键(例如使用--foo --bar --baz 参数运行时),此解决方案会给出非常意外的结果
  • 是的,它会......但这不是 OP 指定的输入。 ..如果它像他的例子一样狭窄,这会很好:P ...如果他需要更多的聪明才智...它很容易改变以适应简单事物的需求...如果他需要更高级的东西,他应使用 cmets 中建议的 --var name=val 语法
【解决方案3】:

在使用字典理解的较新 Python 中,您可以使用这样的单行:

ll = sys.argv[1:]
args = {k[2:]:v for k,v in zip(ll[::2], ll[1::2])}
# {'v1': 'k1', 'v2': 'k2', 'v3': 'k3'}

万一你的用户搞砸了配对,它没有任何灵活性,但它会是一个快速的开始。

可以使用生成器从sys.argv[1:] 中弹出成对的字符串。这将是建立灵活性和错误检查的好地方。

def foo(ll):
    ll = iter(ll)
    while ll:
        yield ll.next()[2:], ll.next()
{k:v for k,v in foo(ll)}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 2013-10-20
    相关资源
    最近更新 更多