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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习笔记__9.4章 序列化相关的知识,希望对你有一定的参考价值。

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

1、概览

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

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

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

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

2pickle模块

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保存那些不重要的数据

3JSON的序列化

如果要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式。而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中读取字符串并反序列化

3class序列化为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()函数转换成一个可序列为JSONdict对象,然后再被顺利序列化为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>


以上是关于Python学习笔记__9.4章 序列化的主要内容,如果未能解决你的问题,请参考以下文章

Python学习笔记(二十五)序列化_JSON基础

Python学习笔记__3.1章 切片

Python学习笔记__7.2章 使用@property

Python学习笔记__14章 virtualenv

Python学习笔记__8章错误调试和测试__8.1章错误处理

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