python将字符串转换成json的方法小结
最近在工作中遇到了一个小问题,如果要将字符串型的数据转换成dict类型,我第一时间就想到了使用json函数。但是里面出现了一些问题
1、通过json来转换:
In[1]:importjson In[2]:mes='{"InsId":2,"name":"lege-happy","CreationTime":"2019-04-23T03:18:02Z"}' In[3]:mes_to_dict=json.loads(mes) In[4]:printtype(mes_to_dict)
以上的方式转换是没问题的,但是加入mes的格式为mes='{"InsId":2,"name":"lege-happy","CreationTime":"2019-04-23T03:18:02Z"}'的时候使用json来转换的时候又会发生什么呢?
In[5]:importjson In[6]:mes="{'InsId':1,'name':'lege-error','CreationTime':'2019-04-24T03:18:02Z'}" In[7]:mes_to_dict=json.loads(mes) --------------------------------------------------------------------------- ValueErrorTraceback(mostrecentcalllast)in () ---->1mes_to_dict=json.loads(mes) /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.pycinloads(s,encoding,cls,object_hook,parse_float,parse_int,parse_constant,object_pairs_hook,**kw) 336parse_intisNoneandparse_floatisNoneand 337parse_constantisNoneandobject_pairs_hookisNoneandnotkw): -->338return_default_decoder.decode(s) 339ifclsisNone: 340cls=JSONDecoder /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.pycindecode(self,s,_w) 364 365""" -->366obj,end=self.raw_decode(s,idx=_w(s,0).end()) 367end=_w(s,end).end() 368ifend!=len(s): /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.pycinraw_decode(self,s,idx) 380""" 381try: -->382obj,end=self.scan_once(s,idx) 383exceptStopIteration: 384raiseValueError("NoJSONobjectcouldbedecoded") ValueError:Expectingpropertyname:line1column2(char1)
所以使用json进行转换存在一个潜在的限制:
由于json语法规定数组或对象之中的字符串必须使用双引号,不能使用单引号(官网上有一段描述是“AstringisasequenceofzeroormoreUnicodecharacters,wrappedindoublequotes,usingbackslashescapes”),因此上面的转换是错误的:
通过eval来转换:
In[8]:mes='{"InsId":2,"name":"lege-happy","CreationTime":"2019-04-23T03:18:02Z"}' In[9]:mes_dict=eval(mes) In[10]:printtype(mes_dict)In[11]: In[11]:mes=mes="{'InsId':1,'name':'lege-error','CreationTime':'2019-04-24T03:18:02Z'}" In[12]:mes_dict=eval(mes) In[13]:printtype(mes_dict)
上面的例子可以看出进行转换的时候不存在使用json转换的问题,但是我们需要注意的是使用eval会存在安全问题,比如:
串型的输入直接计算。比如,她会将'1+1'的计算串直接计算出结果。
In[14]:value=eval(raw_input('pleaseinputavaluestring:')) pleaseinputavaluestring:2+2 In[15]:value Out[15]:4
从上面来看,eval功能可谓非常强大,即可以做string与list,tuple,dict之间的类型转换,还可以做计算器使用!更有甚者,可以对她能解析的字符串都做处理,而不顾忌可能带来的后果!所以说eval强大的背后,是巨大的安全隐患!!!
比如说用户恶意输入下面的字符串:
open(r'D://filename.txt','r').read() __import__('os').system('dir') __import__('os').system('rm-rf/etc/*')
那么eval就会显示你电脑目录结构,读取文件,删除文件等等。如果是格盘等更严重的操作,她也会照做不误!!!显然这个不符合我们的需求!
通过literal_eval转换:
In[20]:importast In[21]:mes='{"InsId":2,"name":"lege-happy","CreationTime":"2019-04-23T03:18:02Z"}' In[22]:mes_dict=ast.literal_eval(mes) In[23]:printtype(mes_dict)In[24]: In[24]: In[24]:mes=mes="{'InsId':1,'name':'lege-error','CreationTime':'2019-04-24T03:18:02Z'}" In[25]:mes_dict=ast.literal_eval(mes) In[26]:printtype(mes_dict)
使用ast.literal_eval进行转换既不存在使用json进行转换的问题,也不存在使用eval进行转换的安全性问题,因此推荐使用ast.literal_eval。
我们来看看官方文档怎么描述literal_eval的:
defliteral_eval(node_or_string): """ SafelyevaluateanexpressionnodeorastringcontainingaPython expression.Thestringornodeprovidedmayonlyconsistofthefollowing Pythonliteralstructures:strings,numbers,tuples,lists,dicts,booleans, andNone. """
意思说ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的python类型,如果是则进行运算,否则就不进行运算。
比如说上面的计算操作,及危险操作,如果换成了ast.literal_eval(),都会拒绝执行。
所以个人推荐大家转换dict的时候,出于安全考虑对字符串进行类型转换的时候,最好使用ast.literal_eval()函数!
总结
以上所述是小编给大家介绍的python将字符串转换成json的方法小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!