有没有办法在从命令行调用Python脚本时实现** kwargs行为

时间:2014-01-20 15:06:47

标签: python

说我有如下功能:

def foo(**kwargs):
    print kwargs

然后调用这个函数,我得到了所有kwargs这个方便的小字典。

>>> foo(a = 5, b = 7)
{'a': 5, 'b': 7}

我想直接对从命令行调用的脚本执行此操作。所以输入:

python script.py a = 5 b = 7

会为上面的示例创建一个类似的dict。可以这样做吗?

这是我到目前为止所拥有的:

import sys

kwargs_raw = sys.argv[1:]
kwargs = {key:val for key, val in zip(kwargs_raw[::3], kwargs_raw[1::3])}
print kwargs

这就是产生的结果:

Y:\...\Python>python test.py a = 5 b = 7
{'a': '5', 'b': '7'}

所以你可能想知道为什么这不够好

  1. 它非常有条理,因此如果ab是其他字符串,整数或浮点数,它将无效。
  2. 我无法确定用户是否打算将5作为int,string或float
  3. 我之前在这里见过ast.literal_eval(),但我无法弄清楚如何让它发挥作用。我的尝试都失败了:

    >>> ast.literal_eval("a = 5")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "Y:\admin\Anaconda\lib\ast.py", line 49, in literal_eval
        node_or_string = parse(node_or_string, mode='eval')
      File "Y:\admin\Anaconda\lib\ast.py", line 37, in parse
        return compile(source, filename, mode, PyCF_ONLY_AST)
      File "<unknown>", line 1
        a = 5
    

    >>> ast.literal_eval("{a:5,b:7}")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "Y:\admin\Anaconda\lib\ast.py", line 80, in literal_eval
        return _convert(node_or_string)
      File "Y:\admin\Anaconda\lib\ast.py", line 63, in _convert
        in zip(node.keys, node.values))
      File "Y:\admin\Anaconda\lib\ast.py", line 62, in <genexpr>
        return dict((_convert(k), _convert(v)) for k, v
      File "Y:\admin\Anaconda\lib\ast.py", line 79, in _convert
        raise ValueError('malformed string')
    ValueError: malformed string
    

    如果重要,我在Windows 7 64位上使用32位的Python 2.7.6。提前致谢

1 个答案:

答案 0 :(得分:4)

您正在寻找的正是寻找的是一种解析命令行参数的方法。请查看argparse模块:http://docs.python.org/2/library/argparse.html#module-argparse

或者,如果您真的想以字典形式提供参数,只需使用json模块:

import json, sys

# Run your program as:
# python my_prog.py "{'foo': 1, 'bar': 2}"
# (the quotes are important)
data = json.loads(sys.argv[1])