序列化

在程序运行的过程中,所有的变量都储存在内存中,例如定义一个dict

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

可以随时修改变量,比如把name修改为'Bill',但是一旦程序结束,变量所占用的内存就被OS完全回收。如果没有把修改后的'Bill'存储到磁盘上,下次重新运行程序,变量又会被初始化为'Bob'。

序列化

把变量从内存中变为可存储或传输的过程称为序列化,在Python中称为pickling,其他语言中称为serilization、marshalling、flattening等等。

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

反序列化:把变量内容从序列化的对象重新读到内存中,unpickling。

Python的序列化在pickle模块中,举例,我们想把之前创建的Dict对象序列化并写入文件中:

import pickle
d=dict(name='Bob',age=20,score=88)
pickle.dumps(d)
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00Bobq\x02X\x03\x00\x00\x00ageq\x03K\x14X\x05\x00\x00\x00scoreq\x04KXu.'

pickle.dumps()方法把任意对象序列化为一个bytes,然后就可以把这个bytes写入文件。

或者用另一个方法pickle.dump()直接把对象序列化后写入一个file-like Object:

f=open('dump.txt','wb')
pickle.dump(d,f)
f.close()

我们直接查看dump.txt文件时,看到的是一堆混乱的内容,但这些都是Python保存的对象内部信息。

之后我们再进行反序列化,把对象从磁盘读到内存,可以先把内容读到一个bytes,然后用pickle.loads()方法反序列化出对象,也可以直接用pickle.load()方法直接从一个file-like Object中直接反序列化出对象。

#pickle.load() 参数是file-like Object
with open('dump.txt','rb') as f:
d2=pickle.load(f) d2
{'name': 'Bob', 'age': 20, 'score': 88} #pickle.loads() 参数是二进制Data
with open('dump.txt','rb') as f:
d=f.read()
N=pickle.loads(d) N
{'name': 'Bob', 'age': 20, 'score': 88}

Python的序列化库pickle可以保存数据的类型,例如将一个dict进行序列化后,再进行反序列化,得到的仍是一个dict(这一点很重要),且其值与之前的dict相同。

存在的问题:python的Pickle只能作用于Python,不能用于其他语言,甚至Python不同的版本也不兼容。因此,只能用pickle保存那些不重要的内容,这样不能成功的反序列化也没关系。

JSON

上文结尾提到,pickle不能用于python之外的语言序列化对象,为了解决这一问题,可以把对象序列化为标准格式,比如XML;但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,而且比XML快,并且可以直接在Web页面中读取,非常方便。

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

JSON Python
{} dict
[] list
'String' str
123.456 int或float
true/false True/Flase
null None

Python → Json

Python内置的json模块提供了完善的Python对象到JSON格式的转换。举例,如何把Python对象转化为JSON:

import json
d=dict(name='Bob',age=20,score=90)
json.dumps(d) '{"name": "Bob", "age": 20, "score": 90}'

json.dumps()返回一个str,其中的内容就是标准JSON。同理,json.dump()方法可以直接把JSON写入一个file-like Object。

with open('Json.txt','w') as f:
json.dump(d,f) with open('Json.txt','r') as f:
print(f.read())
{"name": "Bob", "age": 20, "score": 90}

Json → Python

要把JSON反序列化为Python对象,则要用loads()或者load()方法,前者把JSON的字符串反序列化,后者直接从file-like Object中读取字符串并且反序列化

#json.loads() 从JSON字符串中反序列化
S=json.dumps(d)
json.loads(S)
{'name': 'Bob', 'age': 20, 'score': 90} #json.load() 从file-like Object中反序列化
with open('Json.txt','r') as f:
S2=json.load(f) S2
{'name': 'Bob', 'age': 20, 'score': 90}

由于JSON标准规定JSON编码是UTF-8,所以我们总是可以正确地在Python的str与JSON字符串间转换。

JSON复杂对象的序列化

从之前的表格中,可以看出几种常用类型从JSON到Python间格式的变化。

但是并不存在一种class间的变化,即无法将我们自定义的class类化为JSON,如果直接用dumps转化一个class时,会出现TypeError的错误

import json
class Student():
def __init__(self,name,age,score):
self.name=name
self.age=age
self.score=score S=Student('Bob',20,90)
print(json.dumps(S)) TypeError: Object of type Student is not JSON serializable

这是因为,默认情况下,dumps不知道如何将Student实例变为一个JSON的{}对象

解决方法:

通过修改dumps()的参数default,我们需要为要进行转化的对象专门写一个转换函数,再把函数作为default参数传进去:

def Student2dict(S):
return {
'name':S.name,
'age':S.age,
'score':S.score
}
S=Student('Bob',20,90)
print(json.dumps(S,default=Student2dict))

但是该转换函数,只对Student对象起作用,对于其他的类对象,同样不起作用。

一个通用、简便的任意class到JSON转换的语句为:

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

因为class通常都有一个__dict__属性,它是一个dict,用来存储实例变量。当然也有例外,比如定义了__slot__的class(__slot__属性:规定了类只能有的属性)。

JSON逆序列化

与dumps类似,需要手写一个从JSON到class的方法,并将其作为json.loads()方法的object_hook参数传入。

def Dict2Student(D):
return Student(D['name'],D['age'],D['score'])
S2=json.loads(D,object_hook=Dict2Student)
print(S2)
<__main__.Student object at 0x00000165B0EF8CC8>

打印出的是反序列化的Student实例对象。

总结:

1、几个方法的用法:

d=json.dumps(S) #json序列化
json.dump(f,S) #json序列化 将S序列化保存到file-like Object f中
S=json.loads(d) #json逆序列化
S=json.load(f) #从file-like Object f中逆序列化数据到S中

关于load方法,不是json.load(f,S) 而是 S=json.load(f)

2、修改json.dumps方法的default参数,一种简单、通用的class对象序列化为dict的方法:

D=json.dumps(S,default=lambda obj:obj.__dict__)

3、逆序列化时,要修改的loads方法的参数为object_hook

4、如果想要正常显示中文,需要在dump时添加参数ensure_ascii=False

Python:序列化 pickle JSON的更多相关文章

  1. Python 序列化 pickle/cPickle模块

    Python 序列化 pickle/cPickle模块 2013-10-17 Posted by yeho Python序列化的概念很简单.内存里面有一个数据结构,你希望将它保存下来,重用,或者发送给 ...

  2. Python序列化之json与pickle

    1.json介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...

  3. python序列化模块json和pickle

    序列化相关 1. json 应用场景: json模块主要用于处理json格式的数据,可以将json格式的数据转化为python的字典,便于python处理,同时也可以将python的字典或列表等对象转 ...

  4. python 序列化之JSON和pickle详解

    JSON模块 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类 ...

  5. Python序列化-pickle和json模块

    Python的“file-like object“就是一种鸭子类型.对真正的文件对象,它有一个read()方法,返回其内容.但是,许多对象,只要有read()方法,都被视为“file-like obj ...

  6. python序列化模块 json&&pickle&&shelve

    #序列化模块 #what #什么叫序列化--将原本的字典.列表等内容转换成一个字符串的过程叫做序列化. #why #序列化的目的 ##1.以某种存储形式使自定义对象持久化 ##2.将对象从一个地方传递 ...

  7. Python序列化,json&pickle&shelve模块

    1. 序列化说明 序列化可将非字符串的数据类型的数据进行存档,如字典.列表甚至是函数等等 反序列化,将通过序列化保存的文件内容反序列化即可得到数据原本的样子,可直接使用 2. Python中常用的序列 ...

  8. python使用pickle,json等序列化dict

    import pickle, json, csv, os, shutil class PersistentDict(dict): ''' Persistent dictionary with an A ...

  9. Python序列化之Json基础

    python的序列化就是将python的基本对象转换为字符串的过程,反之则是反序列化. 序列化类型: -> import json import pickle 序列化定义: 序列化:对象.列表. ...

随机推荐

  1. 什么是协程(第三方模块gevent--内置模块asyncio)

    目录 一:协程 1.什么是协程? 2.携程的作用? 3.安装第三方模块:在命令行下 二:greenlet模块(初级模块,实现了保存状态加切换) 三: gevent模块(协程模块) 1.time 模式协 ...

  2. opencvsharp 根据row方向和面积筛选连通域的两种方式

    ConnectedComponents cc = Cv2.ConnectedComponentsEx(tempMat);//相当于halcon的connection获取全部连通域 int blobnu ...

  3. JavaCV的摄像头实战之六:保存为mp4文件(有声音)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. PHP面试常考内容之面向对象(1)

    PHP中面向对象常考的知识点有以下几点,我将会从以下几点进行详细介绍说明,帮助你更好的应对PHP面试常考的面向对象相关的知识点和考题. 整个面向对象文章的结构涉及的内容模块有: 一.面向对象与面向过程 ...

  5. 《PHP程序员面试笔试宝典》——如果面试问题曾经遇见过,是否要告知面试官?

    如何巧妙地回答面试官的问题? 本文摘自<PHP程序员面试笔试宝典> 面试中,大多数题目都不是凭空想象出来的,而是有章可循,只要求职者肯花时间,耐得住寂寞,复习得当,基本上在面试前都会见过相 ...

  6. 32、python并发编程之背景知识

    目录: 一 引子 二 为什么要有操作系统 三 什么是操作系统 四 操作系统与普通软件的区别 五 操作系统发展史 六 总结视频链接: 一 引子 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的 ...

  7. Solution -「Ynoi 2018」「洛谷 P4117」五彩斑斓的世界

    \(\mathcal{Description}\)   Link.   给定序列 \(\{a_n\}\),处理 \(m\) 次操作: 给定 \(l,r,x\),把 \([l,r]\) 内所有 \(&g ...

  8. Solution -「多校联训」神

    \(\mathcal{Description}\)   Link.   给定 \(n\) 阶排列 \(a\),\(q\) 次询问,每次给出 \(1\le l_1\le r_1<l_2\le r_ ...

  9. Solution -「JOISC 2021」「LOJ #3491」道路建设

    \(\mathcal{Description}\)   Link.   平面上有 \(n\) 个互不重合的点 \((x_{1..n},y_{1..n})\),求其两两曼哈顿距离的前 \(m\) 小值. ...

  10. Solution -「AGC 034C」Tests

    \(\mathcal{Description}\)   Link.   给定非负整数序列 \(\{l_n\},\{r_n\},\{b_n\},X\),求最小的 \(s\),使得存在非负整数序列 \(\ ...