内置模块之序列化模块

序列化模块:json模块和pickle模块

前提:

  试想一下,你没有这种需求,想把一个字典或者列表直接存储起来,等下次再用,但是这些数据类型是存储在内存中的,程序结束后内存就会被释放了。通过之前学习的内容,如果想把数据永久地存储下来,可以存储到文件里面,可是文件中只能储存字符串类型,或者那么你的这种需求能够实现吗?

  你灵机一动,想到了强大的eval()内置函数,通过eval就能够操作字符串啊。

stu = {'name':'he','age':23}
ret = str(stu)                    #把字典转换为字符串类型
print(eval(ret),type(eval(ret)))
》》》
{'name': 'he', 'age': 23} <class 'dict'>

  但是强大的eval()的安全性却得不到保证,如果在文件中读取出来的是一条类似于'rm /'之类的命令,后果不堪设想。

   所以在三个场景中是不建议使用eval函数的:

   1.用户输入的时候  2.文件读入的时候  3.网络传输的时候

   这个时候要完成你的需求,就需要用到新的概念:序列化。

序列化:

  将一个对象从内存中转换为可存储(字符串类型)或者可传输(bytes)类型的过程,就叫做序列化过程。在python中叫做pickling,通俗点说,就是序列化就是将其他数据类型转换为字符串/bytes类型的过程。

为什么要用序列化:

  (1)持久化数据类型

  (2)跨平台进行交互。不同的编程语言都用协商好的序列化格式,那么便能打破平台/语言之间的限制,实现跨平台数据交互。

  

json模块

  json格式在各个语言之间都是通用的序列化格式。在json格式中,所有的字符串都是""双引号的。

  json的优点:

    所有的数据类型都是各个语言通用的。在各个编程语言中都支持。

  json的缺点:

    1. json只是支持非常少的数据类型

    2. 对数据类型的约束十分严格。

      (1)字典中的key必须是字符串。

      (2)json只支持列表,字典,数值,字符串,布尔值。

json的用法:

# 序列化过程--json.dumps()
stu = {'name':'he','age':23,1:('hello','python')}
stu_json = json.dumps(stu)
print(stu_json,type(stu_json))
>>>
# 得到序列化后的结果,确实是字符串类型,但是也体现了json对数据类型的严苛要求
# 字典中的元素被转化为了列表形式
{"name": "he", "age": 23, "1": ["hello", "python"]} <class 'str'>

#反序列化过程--json.loads()
stu = json.loads(stu_json)
print(stu,type(stu))
>>>
# 反序列化得到了原来的字典类型,但是还是json格式的约束,原字典中的元组变成了列表
# WTF...这种更改了数据类型的操作,显示是不能令python开发者满意的
{'name': 'he', 'age': 23, '1': ['hello', 'python']} <class 'dict'>

   如果想把数据类型直接序列化到一个文件中,json模块也为我们提供了两个方法:json.dump()和json.load()

# 序列化进文件中
import json
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)       #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()

f = open('json_file')
dic2 = json.load(f)    #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)

  如果文件中存在很多数据,但是load方法只能去第一个数据,这种情况下,需要怎么办?这种情况下,就只能通过打开文件,通过loads()方法读取。

import json
with open('file_path','r')  as f:
    for line in f:
        ret = json.loads(line.strip())
        print(ret)

pickle模块

  由于json格式对python数据类型的支持不是那么完美,如果只是在python程序之间交互,使用pickle模块的支持性会更好。但是不足之处就是,pickle只是适用于python语言。

  pickle的优点:

  (1)pickle支持python中的所有数据类型

  (2)pickle会把数据类型序列化成bytes类型

  pickle的缺点:

  (1)pickle只适用于python。

 pickle模块的使用:

import pickle
dic={'name':'alvin','age':23,'sex':'male'}
print(type(dic))#<class 'dict'>
j=pickle.dumps(dic) print(type(j))#<class 'bytes'>
f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes' f.write(j) #-------------------等价于pickle.dump(dic,f) f.close() #-------------------------反序列化 import pickle f=open('序列化对象_pickle','rb') data=pickle.loads(f.read())# 等价于data=pickle.load(f) print(data['age'])

  

  

原文地址:https://www.cnblogs.com/hebbhao/p/9630081.html