|
| 1 | +>所以你们既是神的选民,圣洁蒙爱的人,就要存怜悯、恩慈、谦虚、温柔、忍耐的心。倘若这人与那人有嫌隙,总要彼此包容,彼此饶恕;主怎么饶恕了你们,你们也要怎样饶恕人。在这一切之外,要存着爱心,爱心就是联络全德的。又要叫基督的平安在你们心里作主,你们也为此蒙召,归为一体,且要存感谢的心。(COLOSSIANS 3:12-15) |
| 2 | +
|
| 3 | +#标准库(8) |
| 4 | + |
| 5 | +##json |
| 6 | + |
| 7 | +就传递数据而言,xml是一种选择,还有另外一种,就是json,它是一种轻量级的数据交换格式,如果读者要做web编程,是会用到它的。根据维基百科的相关内容,对json了解一二: |
| 8 | + |
| 9 | +>JSON(JavaScript Object Notation)是一種由道格拉斯·克羅克福特構想設計、輕量級的資料交換語言,以文字為基礎,且易於讓人閱讀。儘管JSON是Javascript的一個子集,但JSON是獨立於語言的文本格式,並且採用了類似於C語言家族的一些習慣。 |
| 10 | +
|
| 11 | +关于json更为详细的内容,可以参考其官方网站:http://www.json.org |
| 12 | + |
| 13 | +从官方网站上摘取部分,了解一下json的结构: |
| 14 | + |
| 15 | +>JSON建构于两种结构: |
| 16 | +
|
| 17 | +- “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。 |
| 18 | +- 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。 |
| 19 | + |
| 20 | +python标准库中有json模块,主要是执行序列化和反序列化功能: |
| 21 | + |
| 22 | +- 序列化:encoding,把一个python对象编码转化成json字符串 |
| 23 | +- 反序列化:decoding,把json格式字符串解码转换为python数据对象 |
| 24 | + |
| 25 | +###基本操作 |
| 26 | + |
| 27 | +json模块相对xml单纯了很多: |
| 28 | + |
| 29 | + >>> import json |
| 30 | + >>> json.__all__ |
| 31 | + ['dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONEncoder'] |
| 32 | + |
| 33 | +**encoding: dumps()** |
| 34 | + |
| 35 | + >>> data = [{"name":"qiwsir", "lang":("python", "english"), "age":40}] |
| 36 | + >>> print data |
| 37 | + [{'lang': ('python', 'english'), 'age': 40, 'name': 'qiwsir'}] |
| 38 | + >>> data_json = json.dumps(data) |
| 39 | + >>> print data_json |
| 40 | + [{"lang": ["python", "english"], "age": 40, "name": "qiwsir"}] |
| 41 | + |
| 42 | +encoding的操作是比较简单的,请注意观察data和data_json的不同——lang的值从元组编程了列表,还有不同: |
| 43 | + |
| 44 | + >>> type(data_json) |
| 45 | + <type 'str'> |
| 46 | + >>> type(data) |
| 47 | + <type 'list'> |
| 48 | + |
| 49 | +将python对象转化为json类型,是按照下表所示对照关系转化的: |
| 50 | + |
| 51 | +|python==>|json| |
| 52 | +|------|----| |
| 53 | +|dict|object| |
| 54 | +|list, tuple|array| |
| 55 | +|str, unicode|string| |
| 56 | +|int, long, float|number| |
| 57 | +|True|true| |
| 58 | +|False|false| |
| 59 | +|None|null| |
| 60 | + |
| 61 | +**decoding: loads()** |
| 62 | + |
| 63 | +decoding的过程也像上面一样简单: |
| 64 | + |
| 65 | + >>> new_data = json.loads(data_json) |
| 66 | + >>> new_data |
| 67 | + [{u'lang': [u'python', u'english'], u'age': 40, u'name': u'qiwsir'}] |
| 68 | + |
| 69 | +需要注意的是,解码之后,并没有将元组还原。 |
| 70 | + |
| 71 | +解码的数据类型对应关系: |
| 72 | + |
| 73 | +|json==>|python| |
| 74 | +|-------|------| |
| 75 | +|object|dict| |
| 76 | +|array|list| |
| 77 | +|string|unicode| |
| 78 | +|number(int)|int, long| |
| 79 | +|number(real)|float| |
| 80 | +|true|True| |
| 81 | +|false|False| |
| 82 | +|null|None| |
| 83 | + |
| 84 | +**对人友好** |
| 85 | + |
| 86 | +上面的data都不是很长,还能凑合阅读,如果很长了,阅读就有难度了。所以,json的dumps()提供了可选参数,利用它们能在输出上对人更友好(这对机器是无所谓的)。 |
| 87 | + |
| 88 | + >>> data_j = json.dumps(data, sort_keys=True, indent=2) |
| 89 | + >>> print data_j |
| 90 | + [ |
| 91 | + { |
| 92 | + "age": 40, |
| 93 | + "lang": [ |
| 94 | + "python", |
| 95 | + "english" |
| 96 | + ], |
| 97 | + "name": "qiwsir" |
| 98 | + } |
| 99 | + ] |
| 100 | + |
| 101 | +`sort_keys=True`意思是按照键的字典顺序排序,`indent=2`是让每个键值对显示的时候,以缩进两个字符对齐。这样的视觉效果好多了。 |
| 102 | + |
| 103 | +###大json字符串 |
| 104 | + |
| 105 | +如果数据不是很大,上面的操作足够了。但是,上面操作是将数据都读入内存,如果太大就不行了。怎么办?json提供了`load()`和`dump()`函数解决这个问题,注意,跟上面已经用过的函数相比,是不同的,请仔细观察。 |
| 106 | + |
| 107 | + >>> import tempfile #临时文件模块 |
| 108 | + >>> data |
| 109 | + [{'lang': ('python', 'english'), 'age': 40, 'name': 'qiwsir'}] |
| 110 | + >>> f = tempfile.NamedTemporaryFile(mode='w+') |
| 111 | + >>> json.dump(data, f) |
| 112 | + >>> f.flush() |
| 113 | + >>> print open(f.name, "r").read() |
| 114 | + [{"lang": ["python", "english"], "age": 40, "name": "qiwsir"}] |
| 115 | + |
| 116 | +###自定义数据类型 |
| 117 | + |
| 118 | +一般情况下,用的数据类型都是python默认的。但是,我们学习过类后,就知道,自己可以定义对象类型的。比如: |
| 119 | + |
| 120 | +以下代码参考:[Json概述以及python对json的相关操作](http://www.cnblogs.com/coser/archive/2011/12/14/2287739.html) |
| 121 | + |
| 122 | + #!/usr/bin/env python |
| 123 | + # coding=utf-8 |
| 124 | + |
| 125 | + import json |
| 126 | + |
| 127 | + class Person(object): |
| 128 | + def __init__(self,name,age): |
| 129 | + self.name = name |
| 130 | + self.age = age |
| 131 | + |
| 132 | + def __repr__(self): |
| 133 | + return 'Person Object name : %s , age : %d' % (self.name,self.age) |
| 134 | + |
| 135 | + |
| 136 | + def object2dict(obj): #convert Person to dict |
| 137 | + d = {} |
| 138 | + d['__class__'] = obj.__class__.__name__ |
| 139 | + d['__module__'] = obj.__module__ |
| 140 | + d.update(obj.__dict__) |
| 141 | + return d |
| 142 | + |
| 143 | + def dict2object(d): #convert dict ot Person |
| 144 | + if '__class__' in d: |
| 145 | + class_name = d.pop('__class__') |
| 146 | + module_name = d.pop('__module__') |
| 147 | + module = __import__(module_name) |
| 148 | + class_ = getattr(module, class_name) |
| 149 | + args = dict((key.encode('ascii'), value) for key,value in d.items()) #get args |
| 150 | + inst = class_(**args) #create new instance |
| 151 | + else: |
| 152 | + inst = d |
| 153 | + return inst |
| 154 | + |
| 155 | + |
| 156 | + if __name__ == '__main__': |
| 157 | + p = Person('Peter',40) |
| 158 | + print p |
| 159 | + d = object2dict(p) |
| 160 | + print d |
| 161 | + o = dict2object(d) |
| 162 | + print type(o), o |
| 163 | + |
| 164 | + dump = json.dumps(p, default=object2dict) |
| 165 | + print dump |
| 166 | + load = json.loads(dump, object_hook=dict2object) |
| 167 | + print load |
| 168 | + |
| 169 | +------ |
| 170 | + |
| 171 | +[总目录](./index.md) | [上节:标准库(7)](./226.md) | [下节:第三方库](./228.md) |
| 172 | + |
| 173 | +如果你认为有必要打赏我,请通过支付宝:**qiwsir@126.com**,不胜感激。 |
0 commit comments