2009-07-05 48 views
20

拋開最佳做法,是否有一個令人信服的理由不是要做到這一點?通過Python的eval()運行JSON?

我正在寫一個谷歌代碼項目,它提供了通過JSON對象提交的數據使用post-commit鉤子。 GC提供了一個HMAC認證令牌以及請求(JSON數據之外),因此通過驗證該令牌,我非常有把握地認爲JSON數據是良性的(因爲沒有任何不信任Google的意思)並且是有效的。

我自己的(簡單)的調查表明,JSON恰好是完全有效的Python,與"\/"轉義序列除外 - 這GC不會出現產生。

所以,我與Python 2.4(即沒有0​​模塊)工作,eval()正在真的誘人。

編輯:備案,我非常多不是問是否這是一個好主意。我是相當意識到它不是,我非常懷疑我將永遠使用這種技術用於任何未來的項目,即使我最終將其用於此項目。我只是想確保我知道我會遇到什麼樣的麻煩。 :-)

回答

28

如果你滿意你的腳本工作的罰款一會兒,然後隨機未能在一些不起眼的邊緣的情況下,我會去的eval。

如果你的代碼是穩健很重要,我會採取加simplejson的時間。你不需要C部分進行加速,所以將某些.py文件轉儲到某個目錄中確實不難。

由於一些可能咬你一個例子,JSON使用Unicode和simplejson返回的Unicode,而EVAL返回str的:

>>> simplejson.loads('{"a":1, "b":2}') 
{u'a': 1, u'b': 2} 
>>> eval('{"a":1, "b":2}') 
{'a': 1, 'b': 2} 

編輯:哪裏的eval()的行爲不同一個更好的例子:

>>> simplejson.loads('{"X": "\uabcd"}') 
{u'X': u'\uabcd'} 
>>> eval('{"X": "\uabcd"}') 
{'X': '\\uabcd'} 
>>> simplejson.loads('{"X": "\uabcd"}') == eval('{"X": "\uabcd"}') 
False 

編輯2:看到了另一個問題,今天所指出的SilentGhost:EVAL不處理真實​​ - >真,假 - >假,空 - >無正確。

>>> simplejson.loads('[false, true, null]') 
[False, True, None] 
>>> eval('[false, true, null]') 
Traceback (most recent call last): 
    File "<interactive input>", line 1, in <module> 
    File "<string>", line 1, in <module> 
NameError: name 'false' is not defined 
>>> 
11

的最佳做法的要點是,在大多數情況下,這是一個壞主意,不予理會。如果我是你,我會使用解析器將JSON解析爲Python。嘗試使用simplejson,當我最後一次嘗試解析JSON時,解析JSON非常簡單,它聲稱與Python 2.4兼容。

我不同意有小點不信任谷歌。我不會不信任他們,但我會驗證你從他們那裏得到的數據。我真的使用JSON解析器的原因正確的在你的問題:

我自己的(簡短)調查表明,JSON恰好是完全有效的Python,除了「/」轉義序列 - 哪個GC似乎不會生成。

是什麼讓你覺得Google Code永遠不會產生這樣的轉義序列?

如果您使用正確的工具,解析是一個解決的問題。如果你試圖採用這樣的快捷方式,你最終會被不正確的假設咬住,或者你會做一些事情,比如當一個解析器已經存在你的選擇語言時,試圖用正則表達式和布爾邏輯來破解解析器。

+0

如果我沒有在託管環境中運行,我可能會*使用simplejson。不幸的是,我對我的Python環境沒有太多的控制權,我懷疑如何添加自定義軟件包會比編寫實際的腳本花費更長的時間;我們正在說50條線,上衣。同樣,我*不知道GC不會開始生成該轉義序列,但如果這樣做,腳本自然會安全地失敗,很明顯它會被破壞,並且修復很容易。 – 2009-07-05 00:52:31

+0

如果解決方法很簡單,爲什麼不先用固定的方法來做? – 2009-07-05 01:29:07

+0

因爲它涉及使用正則表達式來計算反斜槓。目前,腳本中沒有任何正則表達式,如果可以的話,我會這樣做。 :-) – 2009-07-05 01:35:24

-1

eval荷蘭國際集團JSON是有點像試圖通過一個C++編譯器來運行XML。

eval是爲了評估Python代碼。儘管存在一些語法上的相似性,但JSON不是Python代碼。哎呀,不僅不是Python代碼,它不是代碼開始。因此,即使你爲了你的用途而放棄它,我也會認爲這在概念上是一個壞主意。 Python是一個蘋果,JSON是橙味蘇打水。

2

一個主要的區別是,在JSON的布爾是true | false,但Python使用True | False

最重要的理由不這樣做可以概括:eval不應該被用來解釋外部輸入的,因爲這允許執行任意代碼。