我们知道,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使用的坑以及字符编码的更多相关文章

  1. Python中json.loads解析包含\n的字符串会出错

    用python中的json.loads解析字符串,失败了. [解决过程] 1.调试了半天,终于发现,如果把其中的: "呵呵加那么多连接啊\n\n这个标准还是不错的\n\n给大家推荐一个更多的 ...

  2. python中json格式数据输出实现方式

    python中json格式数据输出实现方式 主要使用json模块,直接导入import json即可. 小例子如下: #coding=UTF-8 import json info={} info[&q ...

  3. python的 json.dumps 中文编码

    python的 json.dumps 中文编码 # -- coding: utf-8 -- 的作用:文件内容以utf-8编码 json.dumps 序列化时对中文默认使用的ascii编码, print ...

  4. Python中json的简单读写操作

    Python中json的简单读写操作 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的 ...

  5. python中json的使用

    在编写接口传递数据时,往往需要使用JSON对数据进行封装.python和json数据类型的转换,看作为编码与解码. 编码:json.dumps() Python JSON dict object li ...

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

    json.load()从文件中读取json字符串 json.loads()将json字符串转换为字典类型 json.dumps()将python中的字典类型转换为字符串类型 json.dump()将j ...

  7. python中json.dump()与json.dumps()的区别

    1.将python数据结构转换为json字符串(json.dumps()) >>> import json >>> data={'name':'pipi','age ...

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

    一.概念理解 1.json.dumps()和json.loads()是json格式处理函数(可以这么理解,json是字符串) (1)json.dumps()函数是将一个Python数据类型列表进行js ...

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

    一.json.dumps(i): json中的dumps方法是用来将特定格式的数据进行字符串化的操作,比如列表字典都可以进行字符串化操作然后写入json的file:而且如果是要写入json文件就必须要 ...

随机推荐

  1. org.apache.jasper.compiler.TldLocationsCache tldScanJar

    我在页面上一点击查询.console以下就有例如以下的红色文字: 2014-8-19 15:09:27 org.apache.jasper.compiler.TldLocationsCache tld ...

  2. Atitit. atiJavaExConverter4js  新的特性

    Atitit. atiJavaExConverter4js  新的特性 1.1. V1新特性1 1.2. V2 新特性1 2. Keyword1 3. Catch1 4. Convert n Thro ...

  3. RGB格式等比例缩放

    原理为:将原始图像的每个像素通过一个比例关系式映射到相应的位置. /* lrgb: input 24bits rgb buffer srgb: output 24bits rgb buffer wid ...

  4. pthread_create11121

    #include <stdlib.h> #include <stdio.h> #include <pthread.h> void* test(void* args) ...

  5. python 学习方法

    依据本人的学习经验,我总结了下面十点和大家分享: 1)学好python的第一步.就是立即到www.python.org站点上下载一个python版本号.我建议刚開始学习的人,不要下载具有IDE功能的集 ...

  6. python学习之函数返回值

    python中函数返回值的方式有2种: 1.return语句 说明:return语句执行完后,函数后续的代码将不会被执行 2.yield语句 说明:yield语句返回的是一个迭代器对象,可以通过nex ...

  7. c++ 请抛弃匈牙利命名法 - 变量命名代码风格的建议。

    我只针对c++码农们讲,其他语言不了解不过应该大同小异.曾几何时翻开21天学通c++系列等脑残入门书,都以匈牙利命名法示人(DWORD dwXXX, int nXXX, string strXXX). ...

  8. StoryBoard不使用AutoLayout情况下 按比例快速兼容适配iPhone6/6 Plus教程【转载】

    StoryBoard不使用AutoLayout情况下 按比例快速兼容适配iPhone6/6 Plus教程[转] 声明:本文章是为了后期快速兼容6和6Plus的按比例放大方法,对于部分读者来说可能觉得该 ...

  9. virtualbox 扩容

    http://www.cnblogs.com/xueweihan/p/5923937.html#1

  10. JavaScript 框架(库)

    JavaScript 高级程序设计(特别是对浏览器差异的复杂处理),通常很困难也很耗时. 为了应对这些调整,许多的 JavaScript (helper) 库应运而生. 这些 JavaScript 库 ...