2014-01-20 146 views
3

说我有一个函数如下调用Python脚本时实行** kwargs行为方式:有没有在命令行

def foo(**kwargs): 
    print kwargs 

然后调用这样的功能,我得到这个方便的小所有kwargs的字典。

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

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

python script.py a = 5 b = 7 

会创建一个类似于上面的例子的字典。这可以做到吗?

这是我到目前为止有:

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,字符串或浮动

我以前见过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 

如果它的事项,我使用Python 2.7.6 32位的Windows 7 64位。在此先感谢

+0

你的第二个'ast.literal_eval'电话ISN不工作,因为你没有引用字典的键('a'和'b')。 – senshin

+0

为什么你不通过只有1 argv,然后你评估与评估? 'python script.py“{'a':5,'b':7}'' 然后在你的脚本中你做'kwa = eval(sys.arvg [1])'... – Ernst

+0

'eval'是一个可怕的想法。它将执行任何用户写入的内容(例如'python my_script.py“__import __('shutil')。rmtree('/')”')。请不要这样做。 –

回答

3

看起来你是真的寻找是一种解析命令行参数的方法。看看在​​模块: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]) 
+0

如果我要让用户在字典中输入参数,我不妨使用'''ast.literal_eval()''',对吧? – wnnmaw

+0

编号'literal_eval'不是数据交换格式(它可以在Python的版本之间进行切换,甚至可以在较小的版本之间进行切换),它比JSON慢并且与Python相关。但是,JSON不是我推荐的解决方案:使用'argparse'。 –

+0

良好的调用使用argparse而不是重新发明轮子,并使其在过程中成为正方形。 –