2015-02-09 67 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

相关问题