今天在尝试把一个列表格式的字符串用json.loads转换成列表的时候报错了,字符串的格式be like:
string1 = "['a','b','c','d']"
报错信息为:json.decoder.JSONDecodeError 查阅资料后发现如果要对字符串进行json解码,该字符串的格式必须为正经的json编码格式,也就是说,只能是双引号,不可以是单引号。所以,如果想用json.loads(string),string 就必须是这样:
string2 = '["a","b","c","d"]'
说到json.loads,我们再浅延伸一下json函数。
| 函数 | 描述 |
|---|---|
| json.dumps | 将 Python 对象编码成 JSON 字符串 |
| json.loads | 将已编码的 JSON 字符串解码为 Python 对象 |
| json.load | 接受一个文件对象并返回 json 对象 |
那如果,给定的字符串就是string1该怎么办呢?也有办法,使用ast.literal_eval(string)就可以解决问题。我们先点进函数看一下这个方法:
def literal_eval(node_or_string):
"""
Safely evaluate an expression node or a string containing a Python
expression. The string or node provided may only consist of the following
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
sets, booleans, and None.
"""
安全地计算表达式节点或包含Python表达式的字符串。后面给出了可供转换的字符串或节点的类型。它会判断需要计算的内容计算后是不是合法的python类型,如果是则进行运算,否则就不进行运算,这一点就体现了该方法的安全性。
其实python中还有一个强大的字符串转换方法eval,先看一下它的方法介绍:
def eval(*args, **kwargs): # real signature unknown
"""
Evaluate the given source in the context of globals and locals.
The source may be a string representing a Python expression
or a code object as returned by compile().
The globals must be a dictionary and locals can be any mapping,
defaulting to the current globals and locals.
If only globals is given, locals defaults to it.
"""
eval函数可以把数据还原成它本身或者是能够转化成的数据类型,例如string与list,tuple,dict之间的类型转换,甚至可以做计算器用,比如:
print(eval('1+1'))
结果就会打印2。
但功能功能如此强大的eval是存在很大的安全隐患的,尤其是当传入的字符串为用户输入的时候,如果有用户恶意输入删除文件等表达式,你的文件就真的会被格式化。关于eval具体的安全隐患,大家可以自行食用。
所以,安全起见,我们还是用ast.literal_eval,当字符串为json格式时,用json.loads也是极好的。
参考: