python中序列化之json文件的使用
前言:
因为文件的读写只能进行字符串或比特类型的操作,其他类型只能转换为字符串或比特类型,想要使用时再转换回原来的类型,转换的过程非常复杂。而序列化和反序列化恰好可以很好的解决这个问题。
序列化和反序列化:
序列化就是将数据的信息或数据结构信息通过转换成字符串,以达到存储或传输的效果。
反序列化,顾名思义,就是将字符串转换为原来的类型。
可序列化的数据类型:
数字类型、字符串类型、列表类型、元组类型、字典类型【最常用】
注意:类、实例化对象,函数,集合是无法序列化的。【这点,java里类,实例化对象是可以序列化的啊?】
序列化模块--json模块与pickle模块:
json是通用的序列化模块,几乎所有的编程语言都有json模块,且序列化和反序列化的规则是统一的。因此,我们在python中通过json序列化的数据,在其他语言中都可以反序列化并使用。
json模块的函数
函数 | 参数 | 描述 | 例子 | 返回值 |
dumps | obj | 对象序列化 | json.dumps([1,2]) | 字符串 |
loads | str | 反序列化 | json.loads('[1,2]') | 原始数据类型 |
json是一种序列化的标准,通过json.dumps()函数对对象进行序列化后,对象会以固定的标准返回:
def json_xuliehua():
b_json = json.dumps('str')
print('json serialize:', b_json)
c_json = json.dumps([1,2,3])
print(c_json)
d_json = json.dumps((4, 5, 6))
print(d_json)
# 字典通过序列化后,键值都用双引号包裹,中文转化成比特类型并编码
e_json = json.dumps({'name':'xiao明', 'age': 12})
print(e_json)
输出:
json serialize: "str"
[1, 2, 3]
[4, 5, 6]
{"name": "xiao\u660e", "age": 12}
同时,json也是一种文件格式,.json文件中的内容都是字典通过json序列化之后的内容。
例子:将字典通过json序列化后存入json文件,再从json文件中读取内容转换为字典
def write(path, data):
with open(path, 'w') as f:
if isinstance(data, dict):
_data = json.dumps(data)
f.write(_data)
else:
raise TypeError('data is not dict')
return True
def read(path):
with open(path, 'r') as f:
result = f.read()
result = json.loads(result)
return result
data = {'name':'小明', 'age': 12, 'height': '165cm'}
if __name__ == '__main__':
write('test.json', data)
result = read('test.json')
print(result)
result['sex'] = 'boy' # 对读取的内容操作,再次写入test.json
write('test.json', result)
result = read('test.json')
print(result)
输出:
{'name': '小明', 'age': 12, 'height': '165cm'}
{'name': '小明', 'age': 12, 'height': '165cm', 'sex': 'boy'}
pickle模块的函数:
pickle模块只在python中使用,在其他语言可能无法处理
函数 | 参数 | 描述 | 例子 | 返回值 |
dumps | obj | 对象序列化 | pickle.dumps([1,2]) | 比特 |
loads | byte | 反序列化 | pickle.load('[1,2]') | 原始数据类型 |
注意:和json不同的是,pickle.dumps()返回的是比特类型,load()函数也只支持对比特类型进行反序列化。
思考:pickle模块的使用场景是哪些?可能是有中文的地方?
def pickle_1():
data = {'name':'小明', 'age':17, 'height': '178cm'}
_data = pickle.dumps(data)
print(_data)
dese = pickle.loads(_data)
print(dese)
输出:
b'\x80\x04\x95-\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x06\xe5\xb0\x8f\xe6\x98\x8e\x94\x8c\x03age\x94K\x11\x8c\x06height\x94\x8c\x04178m\x94u.'
{'name': '小明', 'age': 17, 'height': '178m'}
如上,可知,pickle.dumps()函数可以让数据序列化为比特类型,方便在文件中传输比特类型的数据,又可以使用pickle.loads()函数反序列化为原来的数据类型,很方便实用。
进一步:pickle模块还有个load()函数,是处理序列化后的文件的,传参是文件,这个有时间可以研究下。