json python api
摘要:对于python来说,json并不是一种数据类型,可以把它视为函数。json.dumps把字典或列表变成json风格的str类型;json.loads把json风格的str类型变成原来的类型(列表或者字典)
jso官方说明参见:http://json.org/
Python操作json的标准api库参考:http://docs.python.org/library/json.html
对简单数据类型的encoding 和 decoding:
使用简单的json.dumps方法对简单数据类型进行编码,例如:
|
1
2
3
4
5
6
|
import jsonobj= [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]encodedjson= json.dumps(obj)print repr(obj)print encodedjson |
输出:
[[1, 2, 3], 123, 123.123, 'abc', {'key2': (4, 5, 6), 'key1': (1, 2, 3)}]
[[1, 2, 3], 123, 123.123, "abc", {"key2": [4, 5, 6], "key1": [1, 2, 3]}]
通过输出的结果可以看出,简单类型通过encode之后跟其原始的repr()输出结果非常相似,但是有些数据类型进行了改变,例如上例中的元组则转换为了列表。在json的编码过程中,会存在从python原始类型向json类型的转化过程,具体的转化对照如下:

json.dumps()方法返回了一个str对象encodedjson,我们接下来在对encodedjson进行decode,得到原始数据,需要使用的json.loads()函数:
|
1
2
3
4
|
decodejson= json.loads(encodedjson)print type(decodejson)print decodejson[4]['key1']print decodejson |
输出:
<type 'list'>
[1, 2, 3]
[[1, 2, 3], 123, 123.123, u'abc', {u'key2': [4, 5, 6], u'key1': [1, 2, 3]}]
loads方法返回了原始的对象,但是仍然发生了一些数据类型的转化。比如,上例中‘abc’转化为了unicode类型。从json到python的类型转化对照如下:

json.dumps方法提供了很多好用的参数可供选择,比较常用的有sort_keys(对dict对象进行排序,我们知道默认dict是无序存放的),separators,indent等参数。
排序功能使得存储的数据更加有利于观察,也使得对json输出的对象进行比较,例如:
|
1
2
3
4
5
6
7
8
9
10
|
data1= {'b':789,'c':456,'a':123}data2= {'a':123,'b':789,'c':456}d1= json.dumps(data1,sort_keys=True)d2= json.dumps(data2)d3= json.dumps(data2,sort_keys=True)print d1print d2print d3print d1==d2print d1==d3 |
输出:
{"a": 123, "b": 789, "c": 456}
{"a": 123, "c": 456, "b": 789}
{"a": 123, "b": 789, "c": 456}
False
True
上例中,本来data1和data2数据应该是一样的,但是由于dict存储的无序特性,造成两者无法比较。因此两者可以通过排序后的结果进行存储就避免了数据比较不一致的情况发生,但是排序后再进行存储,系统必定要多做一些事情,也一定会因此造成一定的性能消耗,所以适当排序是很重要的。
indent参数是缩进的意思,它可以使得数据存储的格式变得更加优雅。
|
1
2
3
|
data1= {'b':789,'c':456,'a':123}d1= json.dumps(data1,sort_keys=True,indent=4)print d1 |
输出:
{
"a": 123,
"b": 789,
"c": 456
}
输出的数据被格式化之后,变得可读性更强,但是却是通过增加一些冗余的空白格来进行填充的。json主要是作为一种数据通信的格式存在的,而网络通信是很在乎数据的大小的,无用的空格会占据很多通信带宽,所以适当时候也要对数据进行压缩。separator参数可以起到这样的作用,该参数传递是一个元组,包含分割对象的字符串。
|
1
2
3
4
5
|
print 'DATA:',repr(data)print 'repr(data) ,len(repr(data))print 'dumps(data) ,len(json.dumps(data))print 'dumps(data,,len(json.dumps(data,=4))print 'dumps(data,,len(json.dumps(data,=(',',':'))) |
输出:
DATA: {'a': 123, 'c': 456, 'b': 789}
repr(data) : 30
dumps(data) : 30
dumps(data, indent=2) : 46
dumps(data, separators): 25
通过移除多余的空白符,达到了压缩数据的目的,而且效果还是比较明显的。
另一个比较有用的dumps参数是skipkeys,默认为False。 dumps方法存储dict对象时,key必须是str类型,如果出现了其他类型的话,那么会产生TypeError异常,如果开启该参数,设为True的话,则会比较优雅的过度。
|
1
2
|
data= {'b':789,'c':456,(1,2):123}print json.dumps(data,skipkeys=True) |
输出:
{"c": 456, "b": 789}
处理自己的数据类型
json模块不仅可以处理普通的python内置类型,也可以处理我们自定义的数据类型,而往往处理自定义的对象是很常用的。
首先,我们定义一个类Person。
|
1
2
3
4
5
6
7
8
9
|
class Person(object): def __init__(self,name,age): self.name= name self.age= age def __repr__(self): return 'Person % (self.name,self.age)if __name__ == '__main__': p= Person('Peter',22) print p |
如果直接通过json.dumps方法对Person的实例进行处理的话,会报错,因为json无法支持这样的自动转化。通过上面所提到的json和python的类型转化对照表,可以发现,object类型是和dict相关联的,所以我们需要把我们自定义的类型转化为dict,然后再进行处理。这里,有两种方法可以使用。
方法一:自己写转化函数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
'''Created@author:'''import Personimport jsonp= Person.Person('Peter',22)def object2dict(obj): #convert d= {} d['__class__']= obj.__class__.__name__ d['__module__']= obj.__module__ d.update(obj.__dict__) return ddef dict2object(d): #convert if'__class__' in d: class_name= d.pop('__class__') module_name= d.pop('__module__') module= __import__(module_name) class_ = getattr(module,class_name) args= dict((key.encode('ascii'),for key,in d.items())#get inst= class_(**args)#create else: inst= d return instd= object2dict(p)print d#{'age':o= dict2object(d)print type(o),o#<classdump= json.dumps(p,default=object2dict)print dump#{"age":load= json.loads(dump,object_hook= dict2object)print load#Person |
上面代码已经写的很清楚了,实质就是自定义object类型和dict类型进行转化。object2dict函数将对象模块名、类名以及__dict__存储在dict对象里,并返回。dict2object函数则是反解出模块名、类名、参数,创建新的对象并返回。在json.dumps 方法中增加default参数,该参数表示在转化过程中调用指定的函数,同样在decode过程中json.loads方法增加object_hook,指定转化函数。
方法二:继承JSONEncoder和JSONDecoder类,覆写相关方法
JSONEncoder类负责编码,主要是通过其default函数进行转化,我们可以override该方法。同理对于JSONDecoder。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
'''Created@author:'''import Personimport jsonp= Person.Person('Peter',22)class MyEncoder(json.JSONEncoder): def default(self,obj): #convert d= {} d['__class__']= obj.__class__.__name__ d['__module__']= obj.__module__ d.update(obj.__dict__) return dclass MyDecoder(json.JSONDecoder): def __init__(self): json.JSONDecoder.__init__(self,object_hook=self.dict2object) def dict2object(self,d): #convert if'__class__' in d: class_name= d.pop('__class__') module_name= d.pop('__module__') module= __import__(module_name) class_ = getattr(module,class_name) args= dict((key.encode('ascii'),for key,in d.items())#get inst= class_(**args)#create else: inst= d return instd= MyEncoder().encode(p)o= MyDecoder().decode(d)print dprint type(o), |
对于JSONDecoder类方法,稍微有点不同,但是改写起来也不是很麻烦。看代码应该就比较清楚了。
转自:http://www.cnblogs.com/coser/archive/2011/12/14/2287739.html
json python api的更多相关文章
- Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式 目录 Pycharm使用技巧(转载) Python第一天 安装 shell 文件 Py ...
- BotVS开发基础—Python API
代码 import json def main(): # python API列表 https://www.botvs.com/bbs-topic/443 #状态信息 LogStatus(" ...
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (一)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (二)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- 【Ansible】的python api
[Ansible API] Ansible本身就是由python写成,所有其对python形式的API的支持应该不错. 其API分不同的版本,这个版本也就是ansible本身的版本,可以通过ansib ...
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (四)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (三)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- 如何在 Apache Flink 中使用 Python API?
本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink PMC,阿里巴巴高级技术专家 孙金城 分享.重点为大家介绍 Flink Python API 的现状及未来规划, ...
- Appium python API 总结
Appium python api 根据testerhome的文章,再补充一些文章里面没有提及的API [TOC] [1]find element driver 的方法 注意:这几个方法只能通过sel ...
随机推荐
- Infix to postfix conversion 中缀表达式转换为后缀表达式
Conversion Algorithm 1.操作符栈压入"#": 2.依次读入表达式的每个单词: 3.如果是操作数则压入操作数栈: 4.如果是操作符,则将操作符栈顶元素与要读入的 ...
- QML插件扩展2(基于C++的插件扩展)
上一节介绍了纯QML的插件扩展方式,这种扩展方式基本满足大部分的扩展需求,下面开始介绍比较小众的基于C++的扩展 (一)更新插件工程 1.更新MyPlugin工程下的qmldir文件,加入plugin ...
- cssText笔记
style.cssText 用来获取/设置元素的样式 设置: <div id= "a" style= "background: red;"> doc ...
- 用GeneratedKeyHolder获得新建数据主键值
public User createUser(final User user) { final String sql = "insert into sys_users(username, p ...
- dump文件生成与调试(VS2008)
总结一下dump文件生成和调试的方法: 1:用SetUnhandledExceptionFilter捕获未处理的异常,包含头文件<windows.h>.函数原型为: LPTOP_LEVEL ...
- Struts2龙之总结
一.Struts2执行流程: 1.客户端初始化一个指向servlet容器(tomcat)的请求: 2.这个请求经过一系列过滤器(Filter): 3.接着StrutsPrepareAndExecute ...
- android cts 命令的说明
Host help showthis message 帮助文档 exit exitcts command line 退出CTS ls 全部用l替代,--plan直接用p替代,也即 l p .其他类似 ...
- pat L2-006. 树的遍历
L2-006. 树的遍历 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历 ...
- UVALive 2324 Human Gene Functions(动态规划)
题意:求出将两个字符串改成一样长度所能形成最大的相似度. 思路:这个可以说是编辑距离的一个变形,编辑距离最终状态时要两个字符串完全一致,这个就是要求长度一样,而且这个只允许插入“—”这一个字符.模仿编 ...
- EDA 事件驱动框架
事件代表过去发生的事件,事件既是技术架构概念,也是业务概念.以事件为驱动的编程模型称为事件驱动架构EDA. EDA是一种以事件为媒介,实现组件或服务之间最大松耦合的方式.传统面向接口编程是以接口为媒介 ...