Python-序列化

Python-序列化

 

概念:

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象(百度百科)。Python中叫pickling,在其他语言中也被称之为serializationmarshallingflattening

 

pickle

python为对象序列化提供了pickle模块,例:

import pickle

d
= dict(name = 'David', age = 26, score = 88)
print(pickle.dumps(d)) # dumps 函数把任意对象序列化为bytes

# 采用二进制模式
with
open('dump.txt', 'wb') as f:
   
pickle.dump(d,f) # dump 函数把任意对象序列化后直接写入file-                                    # like Object

with
open('dump.txt', 'rb') as f:
   
d = pickle.load(f)# 反序列化

print(d)

注意:

1.    dump和dumps、load和loads函数分别进行对象的序列化和反序列化,后缀有‘s’的表示针对字节对象(二进制对象),没有‘s’的是将序列化对象保存文件或从文件中读取出来。dump() 函数能一个接着一个地将几个对象转储到同一个文件。随后调用 load() 来以同样的顺序检索这些对象。

2.    新的反序列化的变量和原来的变量是完全不相干的对象,它们只是内容相同而已。Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据。

3.    最新版本的pickle协议是二进制格式的。请确认使用二进制模式来打开你的pickle文件,否则当你写入的时候数据会被损坏。

4.    Python 不能 pickle 文件对象(或者任何带有对文件对象引用的对象),因为 Python 在 unpickle 时不能保证它可以重建该文件的状态。

 

5.    什么东西能用pickle模块存储?

1)     所有Python支持的 原生类型 : 布尔, 整数, 浮点数, 复数, 字符串, bytes(字节串)对象, 字节数组, 以及 None.

2)     由任何原生类型组成的列表,元组,字典和集合。

3)     由任何原生类型组成的列表,元组,字典和集合组成的列表,元组,字典和集合(可以一直嵌套下去,直至Python支持的最大递归层数).

4)     函数,类,和类的实例(带警告)。

 

JSON

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,例如JSON。因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

JSON表示的对象就是标准的JavaScript语言的对象,JSONPython内置的数据类型对应如下:

注意到什么被遗漏了吗?元组和 & 字节串(bytes! json 有数组类型, json 模块将其映射到Python的列表, 但是它没有一个单独的类型对应冻结数组(frozen arrays)” (元组)。而且尽管 json 非常好的支持字符串,但是它没有对bytes 对象或字节数组的支持。

 

import json

d
= dict(name = 'David', age = 20, score = 99)

print(json.dumps(d))

with open('json.txt', 'w') as j: # 这里'wb'不可以使用,因为不是字# 符串
   
json.dump(d,j)

with open('json.txt', 'r') as j:
   
d = json.load(j)
print(d)

类对象序列化:

class Student(object):
   
def __init__(
self, name, age, score):
       
self.name = name
        self.age
= age
        self.score
= score
s
= Student('Bob', 20, 90)

js = json.dumps(s, default= lambda obj: obj.__dict__)

# obj.__dict__在这里是为了将类对象转为字典对象,使用json.dump函数# default参数
print(js)

def dict2Student(d):
   
return
Student(d['name'], d['age'], d['score'])

sd = json.loads(js, object_hook=dict2Student)

# 反序列化时,利用object_hook参数,声明字典转换类对象的函数dict2Student。这里注意实际运算过程是先loads()方法转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例
print(type(sd))

注意:

1)      json数据格式是基于文本的, 不是二进制的。 Defaultutf-8

2)      with open('basic-pretty.json', mode='w',encoding='utf-8') as f:

... json.dump(basic_entry, f, indent=2) 如果你给json.dump()函数传入indent参数, 它以文件变大为代价使生成的json文件更可读。indent 参数是一个整数。0 意味着每个值单独一行。大于0的数字意味着每个值单独一行并且使用这个数目的空格来缩进嵌套的数据结构。

 

3)      json 并不区分元组和列表;它只有一个类似列表的数据类型,数组,并且json模块在序列化过程中会安静的将元组和列表两个都转换成json 数组。大多数情况下,你可以忽略元组和列表的区别,但是在使用json 模块时应记得有这么一回事。

          

 

参考:

http://old.sebug.net/paper/books/dive-into-python3/serializing.html

http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143192607210600a668b5112e4a979dd20e4661cc9c97000

 

扩展阅读:

http://www.jb51.net/article/61231.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值