2014-01-20 147 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而不是重新發明輪子,並使其在過程中成爲正方形。 –