python Json与pickle数据序列化

在程序运行的过程中,所有的变量都是在内存中。一旦程序结束,变量所占用的内存就被操作系统全部回收。

为了避免数据丢失,把变量从内存中变成可存储或传输的过程称之为序列化

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

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

先用常规的方法将一个字典写入到文件中

info = {
    'name':"zhang",
    'age':22
}
with open('test.txt','w') as f:
    #字典无法写入文件,必须转换成字符串
    f.write(str(info))

执行程序,查看test.txt文件内容如下:

{'name': 'zhang', 'age': 22}

读取文件内容,加载到内存中,需要用到eval

eval() 将字符串str当成有效的表达式来求值并返回计算结果

with open('test.txt','r') as f:
    data = eval(f.read())
    print(data['name'])

执行输出 zhang

下面介绍 标准用法,用json模块

序列化:

import json
info = {
    'name':"zhang",
    'age':22
}
with open('test.txt','w') as f:
    f.write(json.dumps(info))
    #查看序列化之后的变量类型
    print(type(json.dumps(info)))

执行输出 class 'str'

可以看到类型是字符串了。

反序列化:

import json
with open('test.txt','r') as f:
    data = json.loads(f.read())
    print(data['name'])

执行输出 zhang

json只能处理简单的数据类型,比如:字符串、字典、列表等

不支持函数,类 转换。

json主要用于不同语言之间数据交互

是目前主流的数据交互格式。

那么其他复杂的数据类型,要序列化,怎么办呢?用pickle

pickle,用于python特有的类型 和 python的数据类型间进行转换。

pickle的语法和json是一样的

序列化

import pickle
info = {
    'name':"zhang",
    'age':22
}
#因为pickle之后,类型是二进制,所以模式是wb
with open('test.txt','wb') as f:
    f.write(pickle.dumps(info))
    #查看序列化之后的变量类型
    print(type(pickle.dumps(info)))

执行输出 class 'bytes'

反序列化

import pickle
with open('test.txt','rb') as f:
    data = pickle.loads(f.read())
    print(data['name'])

执行输出 zhang

注意:pickle的数据类型只有python能用,其他语言,比如java是不能识别的。

pickle代码优化

序列化

import pickle
info = {
    'name':"zhang",
    'age':22
}
with open('test.txt','wb') as f:
    pickle.dump(info,f)

执行效果同上

pickle.dump(info,f) 就等同于 f.write(pickle.dumps(info))

反序列化

import pickle
with open('test.txt','rb') as f:
    data = pickle.load(f)
    print(data['name'])

执行效果同上

pickle.load(f) 等同于 pickle.loads(f.read())

举一个特殊例子

多次序列化

这里先序列化一次,修改年龄之后,再序列化一次

import json

info = {
    'name':"zhang",
    'age':22
}
with open('test.txt','w') as f:
    json.dump(info,f)
    info['age'] = 21
    json.dump(info, f)

执行程序,查看test.txt内容

{"name": "zhang", "age": 22}{"name": "zhang", "age": 21}

反序列化

import json
with open('test.txt','r') as f:
    data = json.load(f)
    print(data['name'])

执行程序,报错

json.decoder.JSONDecodeError: Extra data: line 1 column 29 (char 28)

注意:在python 3.0版本中,一个文件只允许序列化一次。

举个场景,VMware Workstation软件可以创建多个快照,并且可以恢复到任意的快照。它是怎么做到的呢?就是每个快照,有独立的文件。

所以在python中,要想序列化多次,必须每次保存的文件是不一样的才行。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏MasiMaro 的技术博文

C 堆内存管理

在Win32 程序中每个进程都占有4GB的虚拟地址空间,这4G的地址空间内部又被分为代码段,全局变量段堆段和栈段,栈内存由函数使用,用来存储函数内部的局部变量,...

1752
来自专栏武军超python专栏

2018年7月22日用python写个人博客时遇到的问题

今天遇到的新单词: subscript  n下标,脚注 integer    n整数,整型 function   n函数 variable   n变量 ...

1102
来自专栏数值分析与有限元编程

Fortran知识|代码错误(input conversion error)

如图所示,提示:input conversion error ? 此时遇到了异常的转换错误。可能是输入数据类型与程序所声明变量类型不一致(比如输入2.5,对应变...

4356
来自专栏大闲人柴毛毛

三分钟理解“状态模式”——设计模式轻松掌握

什么是状态模式? 一个函数原本有很多判断语句,现在把判断语句中的每一种状态封装成一个类,每一个状态类中均有一个handle()函数,该函数能对当前状态做出处理,...

6717
来自专栏从零开始学自动化测试

Selenium2+python自动化49-判断文本(text_to_be_present_in_element)

前言 在做结果判断的时候,经常想判断某个元素中是否存在指定的文本,如登录后判断页面中是账号是否是该用户的用户名。 在前面的登录案例中,写了一个简单的方法,但不是...

3915
来自专栏积累沉淀

死锁

什么是死锁: 是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死...

2109
来自专栏Java架构师历程

JVM的内存区域划分

学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆、栈以及静态数据区。那么在Java语言当中,内存又是如何划分...

2212
来自专栏章鱼的慢慢技术路

Linux操作_grep/egrep工具的使用

1537
来自专栏MasiMaro 的技术博文

C语言中不同变量的访问方式

C语言中的变量大致可以分为全局变量,局部变量,堆变量和静态局部变量,这些不同的变量存储在不同的位置,有不同的生命周期。一般程序将内存分为数据段、代码段、栈段、堆...

1843
来自专栏天天

onload事件

2462

扫码关注云+社区

领取腾讯云代金券