2014-03-06 76 views
0

我聽說ast.literal_eval比eval()更安全,但在更改我的代碼時,出現'格式錯誤的字符串/節點'錯誤。爲什麼ast.literal_eval()似乎忽略聲明的變量?

例如:

bar = False 
incorrect = {"foo":bar} 
correct = {"foo":"bar"} 

ast.literal_eval(incorrect) 

返回錯誤,但

ast.literal_eval(correct) 

返回預期{ 「富」: 「酒吧」}

爲什麼不是第一回評估{ 「foo」:False}

+1

也許你想引用你的字典,因爲否則爲什麼要打擾eval? 'literal_eval('{「foo」:「bar」}')'按預期工作。 – Hyperboreus

+1

你想達到什麼目的? – msvalkon

+1

我想確保沒有惡意代碼進入程序,但我猜literal_eval只是這樣做,只評估文字。除了eval()是否還有其他替代方法考慮了其他值,還是我所要求的矛盾? – EducateMe

回答

4

因爲它不是要這樣做的。從文檔:

安全地評估包含Python表達式的表達式節點或Unicode或Latin-1編碼的字符串 。提供的字符串或節點可能只包含以下Python文字結構:字符串, 數字,元組,列表,字典,布爾值和無。

ast.literal_evaleval旨在將python代碼的字符串表示轉換爲...有效的python代碼。

這是行不通的:

>>> ast.literal_eval({"foo": "bar"}) 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
    File "/usr/lib/python2.7/ast.py", line 80, in literal_eval 
    return _convert(node_or_string) 
    File "/usr/lib/python2.7/ast.py", line 79, in _convert 
    raise ValueError('malformed string') 
ValueError: malformed string <-- Telltale right here. 

那是因爲你已經擁有你正試圖評估一個有效的Python結構。

如果你把引號將整個事情,相反,它會創建一個字典:

>>> ast.literal_eval('{"foo": "bar"}') 
{'foo': 'bar'} 
1

從上ast.literal_eval的documentation

安全評估的表達式節點或一個Unicode或包含Python表達式的Latin-1編碼的字符串。提供的字符串或節點可能只包含以下Python文字結構:字符串,數字,元組,列表,字典,布爾值和無。

這可以用於從不受信任的來源安全地評估包含Python表達式的字符串,而不需要自己解析值。

bar確實False,而不是字面literal_eval看不到變量。它只適用於文字。