python中json.dumps使用的坑以及字符编码

我们知道,python中的字符串分普通字符串和unicode字符串,一般从数据库中读取的字符串会自动被转换为unicode字符串

下面回到重点,使用json.dumps时,一般的用法为:

>>> obj={"name":"测试"}

>>> json.dumps(obj)
‘{"name": "\\u6d4b\\u8bd5"}‘

>>> print json.dumps(obj)
{"name": "\u6d4b\u8bd5"}

>>> json.dumps(obj).encode("utf-8")
‘{"name": "\\u6d4b\\u8bd5"}‘

可以看到这里输出的字符串为普通字符串,但是里面的内容却是unicode字符串的内容,即使对结果进行encode("utf-8") ,因为这个字符串本身就已经编码过了,所有进行encode不会有变化

要想得到字符串的真实表示,需要用到参数ensure_ascii=False(默认为True)

>>> json.dumps(obj,ensure_ascii=False) 
‘{"name": "\xe6\xb5\x8b\xe8\xaf\x95"}‘

>>> print json.dumps(obj,ensure_ascii=False)
{"name": "测试"}

坑:试试下面的用法(比如key是从数据库中读取的,则会以unicode字符串形式存在):

>>> key=u"name"
>>> obj={key:"测试"}  
>>> json.dumps(obj,ensure_ascii=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/json/__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "/usr/lib64/python2.6/json/encoder.py", line 368, in encode
    return ‘‘.join(chunks)
UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe6 in position 1: ordinal not in range(128)

这是因为key和value不能以混合普通字符串和unicode字符串的形式存在

改成下面则正常了(同时为普通字符串或同时为unicode字符串):

>>> key=u"name"
>>> obj={key:u"测试"}
>>> json.dumps(obj,ensure_ascii=False)
u‘{"name": "\u6d4b\u8bd5"}‘
>>> obj={key.encode("utf-8"):u"测试".encode("utf-8")}
>>> json.dumps(obj,ensure_ascii=False)              
‘{"name": "\xe6\xb5\x8b\xe8\xaf\x95"}‘

另外说说还有一个参数default

考虑下面的场景:

>>> class Data:
...     def __init__(self):
...         self.name = ""
...         self.detail = ""
...

>>> data=Data()
>>> data.name="名字"
>>> data.detail="细节"
>>> obj={"data":data}
>>> json.dumps(obj,ensure_ascii=False)

会报下面的异常:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/json/__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "/usr/lib64/python2.6/json/encoder.py", line 367, in encode
    chunks = list(self.iterencode(o))
  File "/usr/lib64/python2.6/json/encoder.py", line 309, in _iterencode
    for chunk in self._iterencode_dict(o, markers):
  File "/usr/lib64/python2.6/json/encoder.py", line 275, in _iterencode_dict
    for chunk in self._iterencode(value, markers):
  File "/usr/lib64/python2.6/json/encoder.py", line 317, in _iterencode
    for chunk in self._iterencode_default(o, markers):
  File "/usr/lib64/python2.6/json/encoder.py", line 323, in _iterencode_default
    newobj = self.default(o)
  File "/usr/lib64/python2.6/json/encoder.py", line 344, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <__main__.Data instance at 0x11e87e8> is not JSON serializable

这是因为json.dumps不知道如何对Data对象进行序列化,需要定义一个函数,并赋给参数default:

>>> def convert_to_builtin_type(obj):
...     d = {}
...     d.update(obj.__dict__)
...     return d
...

>>> json.dumps(obj,ensure_ascii=False, default=convert_to_builtin_type)
‘{"data": {"name": "\xe5\x90\x8d\xe5\xad\x97", "detail": "\xe7\xbb\x86\xe8\x8a\x82"}}‘
>>> print json.dumps(obj,ensure_ascii=False, default=convert_to_builtin_type)
{"data": {"name": "名字", "detail": "细节"}}

def convert_to_builtin_type(obj):
    d = {}
    d.update(obj.__dict__)
    return d

python中json.dumps使用的坑以及字符编码

时间: 2024-10-12 15:49:15

python中json.dumps使用的坑以及字符编码的相关文章

python 中json has no attribute &#39;loads&#39;

在python爬虫时出现了json has no attribute 'loads'问题. 1 可能是没有安装json包,cmd-pip install json, 显示已安装. 2 当前盘中存在json.py文件,导致错误. 因为我的python文件是保存在F盘中的,而F盘中有名为json.py的文件,所以运行程序时首先在F盘中寻找json文件,名称有json的被认为json包,而其中没有loads模块. 3 解决办法:把F盘中的json.py改名为json1.py重新运行程序,问题解决. p

iOS项目中Json转Model的坑

Json转Model json转model,是个开发都会遇到过.都已经9102年了,谁还不会用个第三方框架搞.拿起键盘就是干!打开podfile,把大名顶顶的YYModel写上,pod install一下.再用上ESJsonFormat,直接根据json,都能把model生成好. 特殊处理 啥?返回的字段值不是我们所需的在日常开发中,经常会遇到一些接口字段返回的值,并不是我所需要的类型的情况,这个时候,我们都会对这个字段进行处理.举个栗子: 123456 /** 错误代码 */@property

python中json模块dumps和loads的区分

b=urllib2.urlopen("http://www.baidu.com")a=b.read()#这里读取的是html中的json格式的内容a1=json.loads(a)#把读取到的内容从json转换成Python中的字典格式print a1['消息状态']#用Python中的字典取值方法 a2=json.dumps(a1)#此时a1已经相当于Python中的字典了,不能称之为json了,此法可以把Python中的字典再次转成json

python中json.load()、json.loads()、json.dump()、json.dumps()的区别

json.load()从文件中读取json字符串 json.loads()将json字符串转换为字典类型 json.dumps()将python中的字典类型转换为字符串类型 json.dump()将json格式字符串写到文件中 1.json.load() with open('text.json','r',encoding='utf-8') as f : print(json.load(f)) { "name": "anthony", "sex"

什么是序列化,Python中json的load,loads,dump,dumps和pickle的load,loads,dump,dumps的区别

我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化 json就是一种序列化的传输手段(json序列化的是字典类型的数据类型) Python把一个字典序列化到一个文本文件中,使用json.dump或者dumps,如下: import json dic={'name':'ljj','age':18} data=json.dumps(dic) f=open('json_text','w') f.write(data) f.close() 或者如下: import json dic={'nam

python中json文件处理涉及的四个函数json.dumps()和json.loads()、json.dump()和json.load()的区分

一.概念理解 1.json.dumps()和json.loads()是json格式处理函数(可以这么理解,json是字符串) (1)json.dumps()函数是将一个Python数据类型列表进行json格式的编码(可以这么理解,json.dumps()函数是将字典转化为字符串) (2)json.loads()函数是将json格式数据转换为字典(可以这么理解,json.loads()函数是将字符串转化为字典) 2.json.dump()和json.load()主要用来读写json文件函数 二.代

python中json库中的load、loads、dump、dumps的区别与用法

一.json.dumps(i): json中的dumps方法是用来将特定格式的数据进行字符串化的操作,比如列表字典都可以进行字符串化操作然后写入json的file:而且如果是要写入json文件就必须要进行dumps操作: 二.json.dump(): 和dumps差一个s,功能作用大致上是一样,也是讲数据转换成str格式,最终包括了讲数据写入json文件的一个操作步骤,json.dump(data, file-open,ascii=False),可以包含三个属性,第三个ascii是用来避免出现u

python中json.loads,dumps,jsonify使用

search_info = {'id':132,'user_role':3} print type(search_info) #输出 <type 'dict'> #转为string用dumps print type(json.dumps(search_info)) #输出 <type 'str'> #string转 dict用 loads() print type(json.loads(json.dumps(search_info))) #输出 <type 'dict'>

Python中json的应用(转)

python中的 json 模块使用 注:测试环境 OS:Ubuntu 16.04 LTS Python:Python 2.7.11+ (1)python 中生成 json 字符串: import json data = dict(ret=0, msg="Welcome, Login success!") json_str = json.dumps(data, sort_keys=True) print json_str (2)python 中解析 json字符串: import js