3. 模块
该模块实现了用于序列化和反序列化对象结构的二进制协议。 与json模块不同的是,模块序列化和反序列化的过程调用的是and:
1.模块与json模块的比较 2.模块使用的数据流格式
如上所述,所使用的数据格式是特定于 . 这使得它不受 JSON 或 XDR 等外部标准的限制,但这也意味着非程序可能无法重建该对象。 默认情况下,数据格式使用相对紧凑的二进制表示形式。 如果需要最佳的大小特性,则可以有效地压缩数据。 该模块包含可用于分析生成的数据流的工具。 目前有 5 种不同的协议可供使用。 使用的协议越高,读取生成的数据就需要更新的版本:
注意:在 2.x 中,默认使用协议 v0。 如果指定协议为分配或者,则使用当前可用的最高协议版本; 在3.x中,默认使用v3协议,与其他3版本兼容,但与2版本不兼容。
注意:()是一个比()更原始的概念; 虽然文件对象可以读写,但它不处理持久对象的命名,也不处理持久对象的并发访问(甚至更复杂的问题)。 模块可以将复杂的对象转换为字节流,并将字节流转换为具有相同内部结构的对象。 也许对这些字节流最可能做的事情是将它们写入文件,但也可以通过网络传输它们或将它们存储在数据库中。 该模块提供了一个简单的接口,用于在 DBM 样式的数据库文件上执行和操作对象。
3.模块提供的相关功能
该模块提供的几个序列化/反序列化功能与json模块基本一致:
# 将指定的Python对象通过pickle序列化作为bytes对象返回,而不是将其写入文件
dumps(obj, protocol=None, *, fix_imports=True)
# 将通过pickle序列化后得到的字节对象进行反序列化,转换为Python对象并返回
loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")
# 将指定的Python对象通过pickle序列化后写入打开的文件对象中,等价于`Pickler(file, protocol).dump(obj)`
dump(obj, file, protocol=None, *, fix_imports=True)
# 从打开的文件对象中读取pickled对象表现形式并返回通过pickle反序列化后得到的Python对象
load(file, *, fix_imports=True, encoding="ASCII", errors="strict")
说明:上述方法参数中,*后面的参数都是3.x中新增的,目的是为了兼容2.x,具体使用请参考官方文档。
4.示例:内置数据类型2.x的序列化/反序列化
>>> import pickle
>>>
>>> var_a = {'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}
# 序列化
>>> var_b = pickle.dumps(var_a)
>>> var_b
"(dp0\nS'a'\np1\nS'str'\np2\nsS'c'\np3\nI01\nsS'b'\np4\nF11.1\nsS'e'\np5\nI10\nsS'd'\np6\nNsS'g'\np7\n(I4\nI5\nI6\ntp8\nsS'f'\np9\n(lp10\nI1\naI2\naI3\nas."
# 反序列化
>>> var_c = pickle.loads(var_b)
>>> var_c
{'a': 'str', 'c': True, 'b': 11.1, 'e': 10, 'd': None, 'g': (4, 5, 6), 'f': [1, 2, 3]}
3.x
>>> import pickle
>>>
>>> var_a = {'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}
# 序列化
>>> var_b = pickle.dumps(var_a)
>>> var_b
b'\x80\x03}q\x00(X\x01\x00\x00\x00eq\x01K\nX\x01\x00\x00\x00aq\x02X\x03\x00\x00\x00strq\x03X\x01\x00\x00\x00fq\x04]q\x05(K\x01K\x02K\x03eX\x01\x00\x00\x00gq\x06K\x04K\x05K\x06\x87q\x07X\x01\x00\x00\x00bq\x08G@&333333X\x01\x00\x00\x00cq\t\x88X\x01\x00\x00\x00dq\nNu.'
# 反序列化
>>> var_c = pickle.loads(var_b)
>>> var_c
{'e': 10, 'a': 'str', 'f': [1, 2, 3], 'g': (4, 5, 6), 'b': 11.1, 'c': True, 'd': None}
转储()和加载()
>>> import pickle
>>>
>>> var_a = {'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}
# 持久化到文件
>>> with open('pickle.txt', 'wb') as f:
... pickle.dump(var_a, f)
...
# 从文件中读取数据
>>> with open('pickle.txt', 'rb') as f:
... var_b = pickle.load(f)
...
>>> var_b
{'e': 10, 'a': 'str', 'f': [1, 2, 3], 'g': (4, 5, 6), 'b': 11.1, 'c': True, 'd': None}
>>>
阐明:
5.示例:自定义数据类型的序列化/反序列化
首先来定义一个数据类型:
class Student(object):
def __init__(self, name, age, sno):
self.name = name
self.age = age
self.sno = sno
def __repr__(self):
return 'Student [name: %s, age: %d, sno: %d]' % (self.name, self.age, self.sno)
模块可以直接序列化/反序列化自定义数据类型,而无需编写额外的处理函数或类。
>>> stu = Student('Tom', 19, 1)
>>> print(stu)
Student [name: Tom, age: 19, sno: 1]
# 序列化
>>> var_b = pickle.dumps(stu)
>>> var_b
b'\x80\x03c__main__\nStudent\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Tomq\x04X\x03\x00\x00\x00ageq\x05K\x13X\x03\x00\x00\x00snoq\x06K\x01ub.'
# 反序列化
>>> var_c = pickle.loads(var_b)
>>> var_c
Student [name: Tom, age: 19, sno: 1]
# 持久化到文件
>>> with open('pickle.txt', 'wb') as f:
... pickle.dump(stu, f)
...
# 从文件总读取数据
>>> with open('pickle.txt', 'rb') as f:
... pickle.load(f)
...
Student [name: Tom, age: 19, sno: 1]
4. 模块
它是一个简单的数据存储方案,类似于key-value数据库,可以非常方便的保存对象,内部通过协议实现数据序列化。 只有一个open()函数,该函数用于打开指定的文件(一个持久化字典),然后返回一个shelf对象。 架子是一个持久的、类似字典的对象。 它与“dbm”的不同之处在于它的值可以是任何原始对象——模块可以处理的任何数据。 这包括大多数类实例、递归数据类型以及具有许多共享子对象的对象。 键是普通字符串。
open(filename, flag='c', protocol=None, writeback=False)
flag参数表示打开的数据存储文件的格式,可能的值与dbm.open()函数一致:
数值描述
'r'
以只读模式打开现有数据存储文件
'w'
以读写模式打开现有数据存储文件
'C'
以读写模式打开数据存储文件,如果不存在则创建它
'n'
始终创建一个新的空数据存储文件并以读写模式打开它
参数表示用于序列化数据的协议版本,默认为v3;
该参数表示是否启用回写功能。
我们可以将shelf对象当作一个dict来存储、更改、查询某个key对应的数据。 当操作完成后,只需调用shelf对象的close()函数即可。 当然,你也可以使用上下文管理器(with语句)来避免每次都手动调用close()方法。
示例:内置数据类型操作
# 保存数据
with shelve.open('student') as db:
db['name'] = 'Tom'
db['age'] = 19
db['hobby'] = ['篮球', '看电影', '弹吉他']
db['other_info'] = {'sno': 1, 'addr': 'xxxx'}
# 读取数据
with shelve.open('student') as db:
for key,value in db.items():
print(key, ': ', value)
输出结果:
name : Tom
age : 19
hobby : ['篮球', '看电影', '弹吉他']
other_info : {'sno': 1, 'addr': 'xxxx'}
示例:自定义数据类型操作
# 自定义class
class Student(object):
def __init__(self, name, age, sno):
self.name = name
self.age = age
self.sno = sno
def __repr__(self):
return 'Student [name: %s, age: %d, sno: %d]' % (self.name, self.age, self.sno)
# 保存数据
tom = Student('Tom', 19, 1)
jerry = Student('Jerry', 17, 2)
with shelve.open("stu.db") as db:
db['Tom'] = tom
db['Jerry'] = jerry
# 读取数据
with shelve.open("stu.db") as db:
print(db['Tom'])
print(db['Jerry'])
输出结果:
Student [name: Tom, age: 19, sno: 1]
Student [name: Jerry, age: 17, sno: 2]
五、总结 1、比较
json模块常用于编写Web界面,将数据转换为通用的json格式传递给其他系统或客户端; 也可用于将数据保存在本地文件中,但缺点是以明文形式存储,保密性较差。 另外,如果需要保存内置数据类型,则需要编写额外的转换函数或自定义类。
模块和模块使用其独特的序列化协议,序列化后的数据只能被识别,因此只能在系统内部使用。另外,2.x和
3.x默认使用的序列化协议也不同。 如果需要相互兼容,则在序列化时必须通过参数指定协议版本。 除了上述缺点之外,模块和模块相对于json模块的优点是可以直接对自定义数据类型进行序列化和反序列化,无需编写额外的转换函数或类。
该模块可以看作是该模块的升级版本,因为它使用了序列化协议,但比提供的操作方法更简单、方便。 与其他两个模块相比,该模块在将数据持久化到本地磁盘时有一个明显的优势,那就是它允许我们像字典一样操作序列化的数据,而不必一次性保存或读取所有数据。
2. 建议 3. 附录 所要实现的功能可使用的API
将数据类型转换为 (json)
json。 转储()
将 json 字符串转换为数据类型
json。 负载()
将数据类型以json的形式保存到本地磁盘
json。 倾倒()
将本地磁盘文件中的json数据转换为数据类型
json。 加载()
将数据类型转换为特定的二进制格式
.dumps()
将特定的二进制格式数据转换为数据类型
.loads()
将数据类型以特定的二进制格式保存到本地磁盘
。倾倒()
将本地磁盘文件中特定的二进制格式数据转换为数据类型
。加载()
保存数据类型到本地磁盘或者读取本地磁盘数据并转换为dict类型的数据类型
。打开()
本文永久更新链接地址: