Python序列化(pickle与json)

什么是序列化?

序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化的目的:
1、以某种存储形式使自定义对象持久化;
2、将对象从一个地方传递到另一个地方。
3、使程序更具维护性。

以上是百度百科对序列化的一段阐述;

举个例子,假设我们开发了一个简单的软件,用户对该软件首选项的设置,或者一些可视化的数据提供,这些信息一开始都是存储在内存中的,但我们想要的结果是就算用户将程序关闭,这些数据依然能够保存下来,那么该怎么办呢?
这种功能的实现就是序列化
用户对程序界面的设置,一些信息的上传等,通过序列化把它们存储在硬盘等持久存储介质中;
反过来,当程序再次需要这些信息时,通过反序列化再把它们转移到内存中处理;

那么问题来了,该怎么序列化呢
Python提供了两个模块实现序列化,分别是pickle以及json

pickle

pickle是Python独有的序列化模块,所谓独有,即它序列化后的内容只能在Python内部使用,不能对外交流,甚至不同版本之间的Python彼此都不兼容;

pickle模块提供了四个函数,分别为dump、dumps、load、loads
前两个进行序列化,后两个则是反序列化;

import pickle
a = [1,2,3,4]
print(pickle.dumps(a))
#b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'

可以看到序列化出一堆乱码,这是因为pickle.dumps()方法把任意对象序列化为一个bytes,注意这时序列化内容还未被存入磁盘,之后你可以选择将这个bytes存入磁盘或是进行传输;

而dump直接存入磁盘文件,它要求需要传入两个参数,第一个参数是需要序列化的变量,第二个是将要写入的文件;

f = open('dump.txt','wb')
import pickle
a = [1,2,3,4]
pickle.dump(a,f)
f.close()

f = open('dump.txt','rb')
print(f.read())
f.close()
#b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'

至于loads与load就更不用多说,loads是把 bytes中的数据反序列化,因此我们需要先把文件中的内容读到一个bytes,而load则是一步到位;

import pickle
f = open('dump.txt','rb')
print(pickle.loads(f.read()))
#[1, 2, 3, 4]

import pickle
f = open('dump.txt','rb')
print(pickle.load(f))
#[1, 2, 3, 4]

json

JSON的全称是 JavaScript Object Notation,它最初是为 JavaScript 开发的,但随后成立一种常见的格式,被包括Python在内的多种语言采用;
如果你要在不同的语言之间传递对象,最好的选择就是序列化为JSON,这时因为JSON表示出来的就是一个字符串,可以被所有语言读取,也更方便于硬盘存储或是网络传输;

基本用法:
在JSON中也有dumps、dump、load、loads函数,但与pickle中差不多,唯一的区别在于JSON序列化后的格式为字符型,即str;
关于它们的用法不再赘述,看一个示例

下面的程序将提示用户输入用户名,并保存下来;
我们知道用户输入的数据保存在内存中,要想长久的保存用户名,需要用到序列化;

import json
username = input("What's your name?")
with open('username.json','w') as f_name:
    json.dump(username,f_name)
    print("Welcome you," + username + "!")
##
What's your name?jack
Welcome you,jack!

同时,当前代码的同级目录下会多出一个后缀为 .json 的文件;

如果用户再次登录:

import json
with open('username.json') as f_name:
    username = json.load(f_name)
    print("Welcome back," + username + "!")
# Welcome back,jack!

再进一步,可以把这两个程序合并起来:

import json
try:
    with open("username.json") as f_name:
        username = json.load(f_name)
except FileNotFoundError:
    username = input("What's your name?")
    with open("username.json",'w') as f_name:
        json.dump(username,f_name)
        print("Welcome you," + username + "!")
else:
    print("Welcome back," + username + "!")

序列化一个类:
如果要序列化一个类,比如Student类:

class Student():
    def __init__(self,name,age):
        self.name = name
        self.age = age

怎么做呢?这个时候不能直接使用dump或者dumps函数,否则会报错,这时因为Python并不知道如何把一个类序列化,解决办法是指定dumps的第二个参数;
没错,dumps()还有第二个参数default,除此之外它还有更多的参数,但目前可以先放一放;

default参数实现把任意一个对象变成一个可序列化的对象,但是需要为default指定一个转换函数
更简便的方法是利用类的实例都通有的__dict__属性:

import json
stu = Student('Tom',18)
print(json.dumps(stu,default=lambda obj:obj.__dict__))
##{"name": "Tom", "age": 18}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值