Python学习笔记__9.4章 序列化

# 这是学习廖雪峰老师python教程的学习笔记

1、概览

在程序运行的过程中,所有的变量都是在内存中。但是一旦程序结束,变量所占用的内存就被操作系统全部回收。而如果要保存变量的修改,我们就可以用序列化。

我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling。

序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

2、pickle模块

Python提供了pickle模块来实现序列化 和 反序列化

1、序列化

d = dict(name='Bob', age=20, score=88) # 定义一个字典

# pickle.dumps()——将对象序列化为bytes,并打印出来,需要手动写入文件

>>> import pickle  # 导入pickle模块

>>> pickle.dumps(d)  # 将对象序列化成一个bytes

b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'

# pickle.dump()——将序列化的信息直接写入file-like Object,不打印

>>> f = open('dump.txt', 'wb')  # 创建文件对象

>>> pickle.dump(d, f)  # 将d序列化,二进制格式写入f

>>> f.close()  # 关闭文件对象

2、反序列化

# pickle.loads()——根据生成的bytes 反序列化

x=b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'  #将序列化出的bytes 赋值给 x

>>> pickle.loads(x)  # 反序列化

{'age': 20, 'score': 88, 'name': 'Bob'}

# pickle.load()——读取file-like Object 的数据 反序列化

>>> f = open('dump.txt', 'rb')  #创建可读文件对象。格式为二进制

>>> d = pickle.load(f)  # 从f 中读取数据,反序列化

>>> f.close()

>>> d

{'age': 20, 'score': 88, 'name': 'Bob'}

3、注意

反序列化出的变量和原来的变量是完全不相干的对象,它们只是内容相同而已。

Pickle只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据

3、JSON的序列化

如果要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式。而JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。

Python对象到JSON格式的转换需要json模块,它调用的方法同pickle模块类似。

d = dict(name='Bob', age=20, score=88)

1、序列化

# json.dumps()——序列化并打印

>>> import json

>>> json.dumps(d)

'{"age": 20, "score": 88, "name": "Bob"}'

# json.dump——直接把JSON写入一个file-like Object

2、反序列化

# json.loads()——把JSON的字符串反序列化

>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'

>>> json.loads(json_str)

{'age': 20, 'score': 88, 'name': 'Bob'}

# json.load()——从file-like Object中读取字符串并反序列化

3、class序列化为JSON

1、序列化

import json

class Student(object):

def __init__(self, name, age, score):

self.name = name

self.age = age

self.score = score

s = Student('Bob', 20, 88)

print(json.dumps(s))

如果我们直接将Student的实例序列化为JSON,则会报错。这是因为默认情况下,dumps()方法不知道如何将Student的实例变为一个JSON的{}对象。

而可选参数default可以把任意一个对象变成一个 可序列为  JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可。

def student2dict(std):

return {

'name': std.name,

'age': std.age,

'score': std.score

}

Student实例首先被student2dict()函数转换成一个可序列为JSON的dict对象,然后再被顺利序列化为JSON

>>> print(json.dumps(s, default=student2dict))

{"age": 20, "name": "Bob", "score": 88}

编写专门的函数序列化,太过麻烦。更简洁的方法如下:

# 把任意class的实例变为dict

# 将实例s,传给 obj 参数,然后返回 obj.__dict__就是个dict

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

通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量

>>> s.__dict__

{'name': 'Bob', 'age': 20, 'score': 88}

>>> type(s.__dict__)

<class 'dict'>

2、反序列化

loads()方法首先转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例

# dict 转换为Student() 的函数

def dict2student(d):

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

>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'  # 需要反序列化的json字符串

>>> print(json.loads(json_str, object_hook=dict2student)) 将json_str通过dict2student 转化为Student()

<__main__.Student object at 0x10cd3c190>

原文地址:http://blog.51cto.com/12758568/2116906

时间: 2024-10-08 04:04:09

Python学习笔记__9.4章 序列化的相关文章

Python学习笔记__9.2章 StringIO 和 BytesIO

# 这是学习廖雪峰老师python教程的学习笔记 很多时候,数据读写不一定是文件,也可以在内存中读写. 1.StringIO StringIO顾名思义就是在内存中读写str. 1.1.写入StringIO 要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可. >>> from io import StringIO   #  导入StringIO类 >>> f = StringIO()     # 创建一个实例,赋给f对象 >

Python学习笔记__9章 IO编程

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 IO在计算机中指Input/Output,也就是输入和输出. 由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,所以涉及到数据交换的地方,通常是磁盘.网络等,这些地方就需要IO接口. 数据从内存往外发是Output 数据从外往内存发是Iutput 2.同步IO和异步IO 同步IO:发起IO请求后,等到IO的返回结果,在接着往下执行 异步IO:发起IO请求后,可以去做其他事.IO结果返回后,会通知调用者. 注:本章所讲

Python学习笔记__2.2章 定义函数

# 这是学习廖雪峰老师python教程的学习笔记 1.定义函数 定义一个函数需要有函数名.参数.函数体.函数体中最好还有 传入的参数判断 1.1.函数创建 定义一个函数用def,数据类型检查用isinstance.例子如下: def my_abs(x): if not isinstance(x, (int, float)):    # 判断传入的参数,是否是 ××× 或 浮点形 raise TypeError('bad operand type')  #  抛出错误 if x >= 0: ret

Python学习笔记__3.3章 列表生成式

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式 1.生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list(range(1, 11)) 2.列表生成式 [1x1, 2x2, 3x3, ..., 10x10] [x*x for x in range(1,11)] 3.使用两层循环 >>>[m + n for m in 'ABC'

Python学习笔记__3.2章 迭代

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 当然,不止 list 和 tuple 可以迭代.只要是可迭代对象,无论有无下标,都可以迭代都.包括dict .str .generator 在Python中,迭代是通过for ... in来完成的. 1.1.字典的迭代 # 定义一个字典 d = {'a': 1, 'b': 2, 'c': 3} 迭代 字典

Python学习笔记__3.5章 迭代器

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 我们已经学习了list.tuple.dict.set.str.generator.generator function 这些可以用for 循环的就是可迭代(Iterable)对象. 但其中只有generator 和 generator function,可以被 next() 函数调用. 而能被next函数调用的 Iterable对象,我们称为迭代器(Iterator) 1.1.Iterable 到Iterator 的转化 虽然Itera

Python学习笔记__4.1章 高阶函数

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 我们知道Python内置的求绝对值的函数是abs() # 调用abs()函数可以获得一个值 >>> abs(-10) 10 # 那么,只写abs本身呢 >>> abs <built-in function abs> 可见,abs(-10)是函数调用,而abs是函数本身 1.1.将函数赋给变量 将函数赋给变量只有两种情况: 把函数计算得到的 结果 赋给变量 f=abs(-10) 把 函数本身 赋给变量

Python学习笔记__3.4章 生成器

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 列表元素按照某种算法推算出来,在循环的过程中不断推算出后续的元素.这种一边循环一边计算的机制,称为生成器:generator 1.1.创建 generator 1)方法一 只要把一个列表生成式的[]改成(),就创建了一个generator L = [x * x for x in range(10)]  #  这是列表生成式 g = (x * x for x in range(10)) #  这是generator >>> g &

Python学习笔记__4.5章 偏函数(绑定函数参数)

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 偏函数(Partial function)是functools模块的一个功能 functools.partial的作用就是,在一个已存在的函数基础上.把它的某些参数给固定住(也就是设置默认值),然后返回一个新的函数,调用这个新函数会更简单. 1.1.functools. partial 应用 已知: int 函数可以将 '123' --> 123. int 的 base 参数可以做 N 进制的转换 >>> int('123