python导入自定义模块出错Json库一直失败怎么解决

解决python中json模块loads出来的结构都是unicode的问题_博客园
当前位置: >
>解决python中json模块loads出来的结构都是unicode的问题
解决python中json模块loads出来的结构都是unicode的问题
& 作者:Jerry.Kwan & 来源: 博客园-jerryshome &
在使用python的json模块对json字串反序列化成python对象的时候出现的字符串都是unicode类型,而不是python内置的str类型。在某种使用场景下用户必须做显式的转换才能正常使用,徒增一些麻烦,为解决这一问题封装下述函数。
def convert(input):
if isinstance(input, dict):
return {convert(key): convert(value) for key, value in input.iteritems()}
elif isinstance(input, list):
return [convert(element) for element in input]
elif isinstance(input, unicode):
return input.encode('utf-8')
return input
对于采用python反序列化后的python对象再调用一次convert函数即可,当然也可以再loads的时候指定object_hook即可。
示例如下:
In [38]: data = {'key1': 'data1',
'key2': 'data2'}
In [39]: json_str = json.dumps(data)
In [40]: print json_str
{&key2&: &data2&, &key1&: &data1&}
In [41]: print json.loads(json_str)
{u'key2': u'data2', u'key1': u'data1'}
In [42]: print convert(json.loads(json_str))
{'key2': 'data2', 'key1': 'data1'}
相关阅读:
来源:(微信/QQ:,微信公众号:makaidong-com) &&&&&& 欢迎分享本文,转载请保留出处!
&&&&&& 【原文阅读】:
上一篇:没有了
【相关文章】
每日最新文章
每日最热文章
本周最热文章
本月最热文章
本年最热文章
Powered by
Copyright &
www.makaidong.com, All Rights Reserved扫一扫体验手机阅读
Python中使用Json 以及 Python2.7中json库Bug的处理
<span type="1" blog_id="1304094" userid='
5篇文章,2W+人气,0粉丝
大数据时代的微服务之路
¥51.00490人订阅
<span type="1" blog_id="1304094" userid='Python中用json.loads解码字符串出错:ValueError: No JSON object could be decoded
原文链接:
的过程中,结果又出错:
LINE 106& : INFO&&&& photoInfoJson={id:’29678′,owner:’379879′,ownername:’shanshu’,title:’IMG_3464′,description:”,bucket:’shanshu’,key:’CsFzMuHz’,license:0,stats_notes: 0,albums: [‘&
1880′,],tags:[{name:’′, author: ‘379879’},{name:’澶╁钩灞辫祻绾㈡灚’, author: ‘379879’}],owner:{id: 379879,username: ‘shanshu’,nickname: ‘shanshu’}}&
LINE 110& : INFO&&&& photoInfoJsonAddQuote={‘id’:’29678′,’owner’:’379879′,’ownername’:’shanshu’,’title’:’IMG_3464′,’description’:”,’bucket’:’shanshu’,’key’:’CsFzMuHz’,’license’:0,’stats_not
es’: 0,’albums’: [‘880′,],’tags’:[{‘name’:’′, ‘author’: ‘379879’},{‘name’:’澶╁钩灞辫祻绾㈡灚’, ‘author’: ‘379879’}],’owner’:{‘id’: 379879,’username’: ‘shanshu’,’nickname’: ‘shanshu’&
LINE 112& : INFO&&&& photoInfoJsonDoubleQuote={&id&:&29678&,&owner&:&379879&,&ownername&:&shanshu&,&title&:&IMG_3464&,&description&:&&,&bucket&:&shanshu&,&key&:&CsFzMuHz&,&license&:0,&stats_
notes&: 0,&albums&: [&880&,],&tags&:[{&name&:&&, &author&: &379879&},{&name&:&澶╁钩灞辫祻绾㈡灚&, &author&: &379879&}],&owner&:{&id&: 379879,&username&: &shanshu&,&nickname&: &shans&
photoInfoDict = json.loads(photoInfoJsonDoubleQuote);&
File &D:\tmp\dev_install_root\Python27_x64\lib\json\__init__.py&, line 326, in loads&
return _default_decoder.decode(s)&
File &D:\tmp\dev_install_root\Python27_x64\lib\json\decoder.py&, line 366, in decode&
obj, end = self.raw_decode(s, idx=_w(s, 0).end())&
File &D:\tmp\dev_install_root\Python27_x64\lib\json\decoder.py&, line 384, in raw_decode&
raise ValueError(&No JSON object could be decoded&)&
ValueError: No JSON object could be decoded
【解决过程】
1.参考自己的帖子:
去添加编码参数试试:
photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
photoInfoJsonDoubleQuote
photoInfoJsonAddQuote.replace(
photoInfoDict
json.loads(photoInfoJsonDoubleQuote, &UTF-8&);
logging.info(&photoInfoDict=%s&,
photoInfoDict);
结果是问题依旧。
虽然知道原因,此处json库不支持带BOM的UTF-8,但是此处是获得的字符串photoInfoJson,
所以,没法通过notepad&#43;&#43;等去转换文件为不带BOM的UTF-8。
所以,需要重新想办法。
2.结果手动重新解码和编码:
photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
photoInfoJsonDoubleQuote
photoInfoJsonAddQuote.replace(
photoInfoDict
json.loads(photoInfoJsonDoubleQuoteUtf8);
logging.info(&photoInfoDict=%s&,
photoInfoDict);
ValueError: No JSON object could be decoded
3.结果去用代码测试了下,当前的确本身就是UTF-8的字符串:
&type(photoInfoJson)=&,type(photoInfoJson);
crifanLib.getStrPossibleCharset(photoInfoJson);
但是不知道为何无法解码。
4.直接试试,单引号:
photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
photoInfoDict
json.loads(photoInfoJsonAddQuote);
logging.info(&photoInfoDict=%s&,
photoInfoDict);
看看效果,你的确会出现:
ValueError: Expecting property name: line 1 column 1 (char 1)
5.仍旧再参考:
去试试,把其转换为ANSI的GB18030,:
photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
photoInfoJsonDoubleQuote
photoInfoJsonAddQuote.replace(
photoInfoDict
json.loads(photoInfoJsonAddQuoteAnsi);
logging.info(&photoInfoDict=%s&,
photoInfoDict);
结果问题依旧。
6.参考手册的解释:
去改为unicode试试:
photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
photoInfoJsonDoubleQuote
photoInfoJsonAddQuote.replace(
photoInfoDict
json.loads(photoInfoJsonDoubleQuoteUni);
logging.info(&photoInfoDict=%s&,
photoInfoDict);
结果是问题依据。
7.再去试试,使用GB18030的看看是否能解码:
photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
photoInfoJsonDoubleQuote
photoInfoJsonAddQuote.replace(
photoInfoDict
json.loads(photoInfoJsonAddQuoteAnsi, &GB18030&);
logging.info(&photoInfoDict=%s&,
photoInfoDict);
结果是问题依旧。
8.单独,写上原始字符串,看看能否正确解码:
&&&&&&&&photoInfoJson
&&&&&&&&photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
&&&&&&&&logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
&&&&&&&&photoInfoJsonDoubleQuote
photoInfoJsonAddQuote.replace(
&&&&&&&&photoInfoDict
json.loads(photoInfoJsonDoubleQuote);
&&&&&&&&logging.info(&photoInfoDict=%s&,
photoInfoDict);
结果却又是其他错误:
&&& photoInfoDict = json.loads(photoInfoJsonDoubleQuote);
& File &D:\tmp\dev_install_root\Python27_x64\lib\json\__init__.py&, line 326, in loads
&&& return _default_decoder.decode(s)
& File &D:\tmp\dev_install_root\Python27_x64\lib\json\decoder.py&, line 366, in decode
&&& obj, end = self.raw_decode(s, idx=_w(s, 0).end())
& File &D:\tmp\dev_install_root\Python27_x64\lib\json\decoder.py&, line 382, in raw_decode
&&& obj, end = self.scan_once(s, idx)
ValueError: Invalid control character at: line 1 column 195 (char 195)
其看看195是哪个字符。
结果看到,其中有CR LF:
9.然后去把CR LF去掉:
然后再去运行试试,结果问题依旧。
10.把测试代码变为:
photoInfoJson
结果问题依旧。
11.结果把代码改为:
photoInfoJson
photoInfoJsonAddQuote
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
photoInfoJson);
logging.info(&photoInfoJsonAddQuote=%s&,
photoInfoJsonAddQuote);
photoInfoJsonDoubleQuote
photoInfoJsonAddQuote.replace(
photoInfoDict
json.loads(photoInfoJsonDoubleQuote);
logging.info(&photoInfoDict=%s&,
photoInfoDict);
竟然,终于,可以解码了。。。
其中,是把:
albums: [‘880’,]
albums: [‘880’]
即,把列表类型的&#20540;的内部的最后一个“多余”的逗号去掉,就可以了。
对于列表最后,添加上一个逗号,对于本身Python中的语法,是允许的;
对于其他语言,比如C语言,记得也是允许的。
但是很变态的是,在Python 2.7.3中的json库中,是不支持的。。。
导致,很多人,如果遇到类&#20284;问题,根本无从下手。。。
在Python 2.7.3中的json库中,是不支持的这种的:
albums: [‘880’,]
必须写成:
albums: [‘880’]
解决办法:
对于上述这种非法的字符串:
{id:’29678′,owner:’379879′,ownername:’shanshu’,title:’IMG_3464′,description:’xxx’,bucket:’shanshu’,key:’CsFzMuHz’,license:0,stats_notes: 0,albums: [‘880’,],tags:[{name:’′,
author: ‘379879’},{name:’天平山赏红枫’, author: ‘379879’}],owner:{id: 379879,username: ‘shanshu’,nickname: ‘shanshu’}}
addedSingleQuoteJsonStr
re.sub(r&(,?)(\w&#43;?)\s*?:&,
r&\1'\2':&,
orginalJsonStr);
doubleQuotedJsonStr
addedSingleQuoteJsonStr.replace(&'&,
removedLastCommaInList
re.sub(r&,\s*?]&,
addedSingleQuoteJsonStr);
处理成,合法的:
{id:’29678′,owner:’379879′,ownername:’shanshu’,title:’IMG_3464′,description:’xxx’,bucket:’shanshu’,key:’CsFzMuHz’,license:0,stats_notes: 0,albums: [‘880′],tags:[{name:’’, author: ‘379879’},{name:’天平山赏红枫’, author: ‘379879’}],owner:{id:
379879,username: ‘shanshu’,nickname: ‘shanshu’}}
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?数学才是最牛的语言
Python中Json库loads方法ValueError异常分析
最近用python开发公司网络协议的解析工具,直接从网络抓包pcap文件中解析出协议交换流程.公司协议中二进制和Json两种格式类型共存.针对二进制内容,python的struct这库用起来还是蛮顺手的.针对Json协议部分,首选就是本文的Json库.对于Json库的详细介绍,可以网上搜一把,资料还是很全的.这里讨论的是json库的loads方法.由于struct库获取过来的数据,都是以pythonh中的字符串类型的保存的,所以我采用json的loads方法(load是从文件中加载).于是乎, 问题就出现了, 我使用时loads抛出了一个ValueError异常.查看下程序堆栈信息,可以发现loads方法的调用流程是:loads()-&_default_decoder.decode(s)其中decode的库源代码如下: def decode(self, s, _w=WHITESPACE.match):
"""Return the Python representation of ``s`` (a ``str`` or ``unicode``
instance containing a JSON document)
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
end = _w(s, end).end()
if end != len(s):
raise ValueError(errmsg("Extra data", s, end, len(s)))
return obj
其中WHITESPACE是一个正则表示式对象,其定义代码如下:
WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
就是匹配空白字符的一个正则表达式对象,所以
idx=_w(s, 0).end()就是把字符串前面的空白字符都跳过了soga.
PS:正则表示式对象的match方法的第二个入参,代表匹配的起始位置
然后self.raw_decode完成了字符串内容的解析(相关代码可以自己研究哦),返回了一个obj对象(这货就是我们需要的)和一个end( json格式中‘}’的位置+1,end返回一个开区间的结束位置) ,end现在代表json处理了的字符串的长度
end = _w(s, end).end()
_w这老兄又把end加上了json字符串后面空白字符串的长度(如果有的话).
主题来了:
if end != len(s):
raise ValueError(errmsg("Extra data", s, end, len(s)))如果json处理的字符串长度和我们给的长度不一致,那就game over,抛出一个ValueError异常了.什么情况下会导致长度不统一呢,根据json库的算法,只要你在后面的空白字符再跟上其他非空白字符,那就能得到梦寐以求的ValueError.
由于我要解析的json字符串,后面都会带上c字符结尾符0,所以这就是真相.
我的解决方法是,对到手的json字符串先预处理下:
strJson = "".join([ string.strip().rsplit("}" , 1)[0] ,
"}"] ) 主要就是用rsplit函数切掉最右边“}”后面的字符串.
PS:我是感觉end!=len(s)这个判断不是很好,不过stackoverflow上面一些家伙的解释,是json库不支持解释"{}{}"这种类型的json字符串,从这方法考虑,倒也说的通.
PS2:为什么不支持?有时间,可以自己实现支持{}{}格式的解析
PS3:最后贴上我工具中json串格式转换部分:
def FormatJsonString(string , keySpace = 4):
#处理json对象
def StrJsonObj(objJson , deep ):
lstJson= []&span style="white-space:pre"& &/span&#return "".join([&span style="font-family: Arial, Helvetica, sans-"&StrJsonNote( item , deep)
for item in objJson.items()
for item in objJson.items() :
lstJson.append(StrJsonNote( item , deep) )
return "".join(lstJson)
#处理json节点
def StrJsonNote(objNote , deep):
key , content = objNote
"%s%-*s : " % ("
" * deep , keySpace , key)
return "".join([retStr , StrJsonContent(content , deep)])
#处理json节点内容
def StrJsonContent(content , deep , strTab="" , inList = False):
retStr = ""
if isinstance( content , dict):
if inList == False:
"".join(["\n" , StrJsonObj( content , deep+1 )])
retStr = StrJsonObj( content , deep+1 )
elif isinstance( content , list):
lstResult = ["\n"]
nextDepp = deep+1
for item in content:
lstResult.append(StrJsonContent(item , nextDepp , "
" * nextDepp , True) )
count += 1
retStr = "".join(lstResult)
elif isinstance( content , unicode):
"".join( [('%s"%s"' % ( strTab , content) ) , "\n"] )
"".join( [("%s%s" % (strTab , content))
return retStr
strJson = "".join([ string.strip().rsplit("}" , 1)[0] ,
#处理外部的原始json字符串
objJson = json.loads(strJson)
#转换成json字典
return StrJsonObj(objJson , 0)
python ValueError: Extra data: line 1 column 4 - line 1 column 12585 (char 3
python json及mysql——读取json文件存sql、数据库日期类型转换、终端操纵mysql及python codecs读取大文件问题
eval与json.loads对json的处理小记
[python]json.loads 几种错误 解决方案
python执行json.loads(...)时遇到的错误
[解决办法]Python中使用json.loads解码字符串时出错:ValueError: Expecting property name: line 1 column 2 (char 1)
Python-json.loads\load
python 字符串转换为json时,出现Extra data错误
python json.loads('123')会发生异常吗?
没有更多推荐了,解决Python自带的json序列化工具不能序列化datetime类型数据问题
我的图书馆
解决Python自带的json序列化工具不能序列化datetime类型数据问题
Python自带的json.dumps方法序列化数据时候如果格式化的数据中有datetime类型数据时候会提示错误TypeError: datetime.datetime(, 15, 47, 15) is not JSON serializable搜索出来的解决方案基本都是用Django的DjangoJSONEncoder来解决,为了一个简单的办法引入Django这个大家伙实在有点不知所谓。不过这一点就体现了Django的资料多的优势了正在下决心是否干脆下载了Django的代码去翻出DjangoJSONEncoder这个方法来的时候看到了官方文档中关于json.dumps方法的一个参数(cls)说明:To use a custom JSONEncoder subclass (e.g. one that overrides the default() method to serialize additional types), specify it with the&cls otherwise JSONEncoder is used.然后就看到了官方文档中的一个Demo:&&& import json&&& class ComplexEncoder(json.JSONEncoder):...
def default(self, obj):...
if isinstance(obj, complex):...
return [obj.real, obj.imag]...
return json.JSONEncoder.default(self, obj)...&&& dumps(2 + 1j, cls=ComplexEncoder)'[2.0, 1.0]'&&& ComplexEncoder().encode(2 + 1j)'[2.0, 1.0]'&&& list(ComplexEncoder().iterencode(2 + 1j))['[', '2.0', ', ', '1.0', ']']然后简单扩展了一个JSONEncoder出来用来格式化时间class CJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
return json.JSONEncoder.default(self, obj)使用时候只要在json.dumps增加一个cls参数即可:json.dumps(datalist, cls=CJsonEncoder)
[转]&[转]&[转]&[转]&[转]&[转]&
喜欢该文的人也喜欢

我要回帖

更多关于 黑马python培训班 费用 的文章

 

随机推荐