2015-02-09 65 views
4

我有一個存儲在數據庫字段中的字典作爲字符串。我試圖將其解析爲字典,但json.loads給了我一個錯誤。ast.literal_eval vs json.dumps

>>> c.iframe_data 
u"{u'person': u'Annabelle!', u'csrfmiddlewaretoken': u'wTE9RZGvjCh9RCL00pLloxOYZItQ98JN'}" 

# json fails 
>>> json.loads(c.iframe_data) 
Traceback (most recent call last): 
ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) 

# ast.literal_eval works 
>>> ast.literal_eval(c.iframe_data) 
{u'person': u'Annabelle!', u'csrfmiddlewaretoken': u'wTE9RZGvjCh9RCL00pLloxOYZItQ98JN'} 

爲什麼json失敗和ast.literal_eval的作品?一個比另一個更好嗎?

回答

5

json失敗,因爲您的c.iframe_data值不是有效的JSON文檔。有效的json文檔字符串在雙引號中引用,並且沒有任何用於將字符串轉換爲unicode的u。使用json.loads(c.iframe_data)意味着反序列化c.iframe_data

ast.literal_evalJSON文件是用來當你需要EVAL評估input表達。如果你有Python表達式作爲你想要評估的輸入。

比其他人更受歡迎嗎?

答案是NO

+0

同樣在'json'數據中沒有任何東西像'u'將字符串轉換爲unicode。 – ozgur 2015-02-09 06:21:56

3

因爲這u"{u'person': u'Annabelle!', u'csrfmiddlewaretoken': u'wTE9RZGvjCh9RCL00pLloxOYZItQ98JN'}"是一個Python unicode字符串,而不是一個JavaScript對象符號,在鍍鉻控制檯:

bad = {u'person': u'Annabelle!', u'csrfmiddlewaretoken': u'wTE9RZGvjCh9RCL00pLloxOYZItQ98JN'} 
SyntaxError: Unexpected string 
good = {'person': 'Annabelle!', 'csrfmiddlewaretoken': 'wTE9RZGvjCh9RCL00pLloxOYZItQ98JN'} 
Object {person: "Annabelle!", csrfmiddlewaretoken: "wTE9RZGvjCh9RCL00pLloxOYZItQ98JN"} 

或者您可以使用YAML處理它:

>>> a = '{"person": "Annabelle!", "csrfmiddlewaretoken": "wTE9RZGvjCh9RCL00pLloxOYZItQ98JN"}' 
>>> json.loads(a) 
{u'person': u'Annabelle!', u'csrfmiddlewaretoken': u'wTE9RZGvjCh9RCL00pLloxOYZItQ98JN'} 
>>> import ast 
>>> ast.literal_eval(a) 
{'person': 'Annabelle!', 'csrfmiddlewaretoken': 'wTE9RZGvjCh9RCL00pLloxOYZItQ98JN'} 
>>> import yaml 
>>> a = '{u"person": u"Annabelle!", u"csrfmiddlewaretoken": u"wTE9RZGvjCh9RCL00pLloxOYZItQ98JN"}' 
>>> yaml.load(a) 
{'u"person"': 'u"Annabelle!"', 'u"csrfmiddlewaretoken"': 'u"wTE9RZGvjCh9RCL00pLloxOYZItQ98JN"'} 
>>> a = u'{u"person": u"Annabelle!", u"csrfmiddlewaretoken": u"wTE9RZGvjCh9RCL00pLloxOYZItQ98JN"}' 
>>> yaml.load(a) 
{'u"person"': 'u"Annabelle!"', 'u"csrfmiddlewaretoken"': 'u"wTE9RZGvjCh9RCL00pLloxOYZItQ98JN"'} 
2

json.loads特別用於解析JSON,這是一種非常嚴格的格式。沒有u'...'語法,所有字符串都由雙引號分隔,而不是單引號。使用json.dumps來串行化可被json.loads讀取的內容。

所以json.loads(string)json.dumps(object)的倒數,而ast.literal_eval(string)(隱含地)是repr(object)的倒數。

JSON很好,因爲它是可移植的 - 有幾乎所有語言都可以使用的解析器。所以如果你想發送JSON到一個Javascript前端,你不會有任何問題。例如,您可以使用元組,鍵和字符串不限於字符串的元組,集合和字典。但是,它可以使用元組,集合和字典。

json.loads is significantly faster than ast.literal_eval