JSON 模块

序列化的概念

把对象(变量)从内存中变成可存储或传输的过程称为序列化,序列化之后,就可以把序列化的内容写入磁盘或传输到其他的机器上,反过来,把变量内容从序列化的对象重新读到内存称为反序列化。

在 python 中直接打开文件写入集合会报错,需要将其类型转换为字符串。

1
2
3
4
5
6
7
8
9
dic = {}
f = open('test','w')
f.write(dic)
#TypeError: write() argument must be str, not dict


dic = {}
f = open('test','w')
f.write(str(dic))

dumps 方法

json 模块的 dumps 方法可以直接将要写入的内容转换成字符串的格式,写入指定文件。

1
2
3
4
5
6
import json
dict = {'name':'alex','age':'12'}
data=json.dumps(dict)
f = open('json_test','w')
f.write(data)
f.close()

此时运行程序后,可直接在 json_test 文件中写入 dict 内容,且以字典的格式存储。

dump 方法

dumps 方法需要我们来打开文件,转换数据类型后写入;但是 dump 方法可以省略我们写入和转换的步骤,由该方法自己完成。

格式:dump(arg1,arg2)

第一个参数为要写入的内容,第二个参数为文件句柄。参考如下代码:

1
2
3
4
5
6
7
import json
dict = {'name':'alex','age':'12'}
f = open('json_test','w')
json.dump(dict,f)
f.close()
# data=json.dumps(dict)
# f.write(data)

loads 方法

json 模块的 loads 方法可以直接将要读取的文件内容反序列化后取出,以相同格式的数据类型返回。

1
2
3
4
5
import json
f=open('Json_test','r')
data=f.read()
data=json.loads(data)
print(data['name']) #alex

load 方法

与 dump 方法的使用规则类似,参考如下代码:

1
2
3
4
import json
f = open('json_test','r')
data=json.load(f)
print(data['name']) #alex

注:json load 方法有一个 bug,如果所取字典中的键值对是单引号括起来的,就会报错,同样的代码,但是 json_test 文件中的字典如下:

1
2
3
4
5
6
7
#{’name‘:‘alex’,‘age’:‘12’}

import json
f = open('json_test','r')
data=json.load(f)
print(data['name'])
#json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

pickle 模块

pickle 模块与 json 模块的功能类似,但是 pickle 模块可处理函数等对象的写入,而 json 不行。

当尝试使用 json.dumps 写入一个函数到文件中时,会报出以下错误:

1
2
3
4
5
6
7
8
import json
def foo():
print('ok')
f=open('pickle_test','w')
data=json.dumps(foo)
#Object of type function is not JSON serializable
f.write(data)
f.close()

使用 pickle 模块可以成功执行,将函数写入,pickle 模块是将内容转换为二进制的格式,然后进行文件的写入,所以操作文件时,要设置为 wb 格式。

1
2
3
4
5
6
7
import pickle
def foo():
print('ok')
f=open('pickle_test','wb')
data=pickle.dumps(foo)
f.write(data)
f.close

pickle 存入的文件内容取出时依旧使用 loads 方法,但是不能直接对取出的函数进行调用,因为取出的只是指向内存地址的变量,内存地址已经发生变化。

1
2
3
4
5
6
7
8
import pickle
f=open('pickle_test','rb')
data=f.read()
data=pickle.loads(data)
# Can't get attribute 'foo' on <module '__main__' from 'D://xxx
f.read(data)
f.close
data()

这时如果需要调用,则需要此文件中也有该函数,参考如下代码:

1
2
3
4
5
6
7
8
9
import pickle
def foo():
print('ok')
f=open('pickle_test','rb')
data=f.read()
data=pickle.loads(data)
f.read(data)
f.close
data() #ok

shelve 模块

shelve 模块也可将指定字典内容写入文件中,参见如下代码:

1
2
3
4
5
import shelve
f = shelve.open('shelve_test')
print(type(f)) #<class 'shelve.DbfilenameShelf'>
f['info']={'name':'alex','age':'12'}
f['shoping']={'name':'alex','price':'1000'}

执行后会在当前目录生成三个不同格式的文件,如下:

存储内容如下:

取值方式可直接使用字典类型的取值方式,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import shelve
f = shelve.open('shelve_test')
print(type(f)) #<class 'shelve.DbfilenameShelf'>
f['info']={'name':'alex','age':'12'}
f['shoping']={'name':'alex','price':'1000'}
data=f.get('info')
data1=f.get('shoping')
print(data)
print(data1)

{'name': 'alex', 'age': '12'}
{'name': 'alex', 'price': '1000'}
#alex
#male