ast.literal_eval vs json.dumps

Dav*_*542 8 python parsing json abstract-syntax-tree

我有一个字典作为字符串存储在db字段中.我试图将其解析成一个字典,但json.loads给了我一个错误.

>>> 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'}
Run Code Online (Sandbox Code Playgroud)

为什么json失败并且ast.literal_eval有效?一个比另一个好吗?

sty*_*ane 9

json.loads失败,因为您的c.iframe_data值不是有效的JSON文档.在有效的json文档字符串中引用双引号,并没有像u将字符串转换为unicode.使用json.loads(c.iframe_data)方法反序列化JSON文档c.iframe_data

ast.literal_eval只要你需要eval来评估input表达式,就会使用它.如果您将Python表达式作为要评估的输入.

一个比另一个好吗?

答案是否定的


And*_*gee 5

json.loads专门用于解析JSON,这是一种相当严格的格式。没有u'...'语法,所有字符串都用双引号而不是单引号分隔。用于json.dumps序列化可由 读取的内容json.loads

json.loads(string)的逆也是如此json.dumps(object),而ast.literal_eval(string)是(模糊地) 的逆repr(object)

JSON 很好,因为它是可移植的——几乎每种语言都有它的解析器。因此,如果您想将 JSON 发送到 Javascript 前端,就不会有任何问题。

ast.literal_eval不容易移植,但它稍微丰富一些:例如,您可以使用元组、集合和字典,其键不限于字符串。

json.loads明显快于ast.literal_eval.


hol*_*web 5

我有一个字典,它以字符串形式存储在db字段中。

这是设计错误。尽管完全有可能(有人似乎已经做了)提取repr字典的,但是并不能保证repr可以完全评估对象的。

在只有字符串键以及字符串和数字值的情况下,大多数情况下,Python eval函数将从其repr中再现该值,但是我不确定为什么您认为这会使它成为有效的JSON。

我试图将其解析为字典,但是json.loads给我一个错误。

自然。您没有在数据库中存储JSON,因此期望将其解析为JSON似乎并不合理。尽管ast.literal_eval可以用来解析值很有趣,但是除了相对简单的Python类型之外,没有其他保证。

由于看来您的数据确实仅限于此类类型,因此解决问题的真正方法是通过将字典转换为字符串,json.dumps然后将其存储在数据库中来纠正数据的存储方式。某些数据库系统(例如 PostgreSQL)具有JSON类型,以简化对此类数据的查询,我建议您使用可用的这些类型。

至于哪种“更好”,将始终取决于特定的应用程序,但是JSON被明确设计为一种紧凑的人类可读的机器可解析的格式,用于简单的结构化数据,而您当前的表示形式则基于Python特有的格式。 (例如)很难用其他语言进行评估。JSON是此处适用的标准,您将从中受益。