【Python】pickle&json序列化



2017年10月06日    Author:Guofei

文章归类: 0xb0_Python语法    文章编号: 1211

版权声明:本文作者是郭飞。转载随意,但需要标明原文链接,并通知本人
原文链接:https://www.guofei.site/2017/10/06/pickle.html


pickle是什么

想把某个对象存储起来,可以以数据库的形式,但这种做法有些缺点:

  1. 存储后的数据可以被其它程序调用,违反面向对象封装性原则
  2. 数据库不理解对象,并且会强行使用自己的类型系统

pickle的特点是可以存储对象的同时,保持对象之间的关系。

简要用法

import pickle

with open(filename, 'wb') as f:
    pickle.dump(content, f)

with open(filename, 'rb') as f:
    content = pickle.load(f)


# 或者存到一个变量中
content = ['Hello', 'World', '!']
serialized = pickle.dumps(content) # res 是 bytes 类型的序列化之后的数据
pickle.loads(serialized) # 反序列化:还原

特性

如果对象的引用深度非常深,会报错,可以加下面一段解决

sys.setrecursionlimit(10000)

先进先出

import pickle

a = 'haha'
b = [1, 2, 3]
c = {3: 'ds', 1: '32'}
f1 = open('temp.pkl', 'wb')
pickle.dump(a, f1, True)
pickle.dump(b, f1, True)
pickle.dump(c, f1, True)
f1.close()

f2 = open('temp.pkl', 'rb')
print(pickle.load(f2))
print(pickle.load(f2))
print(pickle.load(f2))
f2.close()

输出:

haha
[1, 2, 3]
{3: 'ds', 1: '32'}

保持对象的引用关系1

import pickle

a = [1, 2, 3]
b = a
f1 = open('temp1.pkl', 'wb')
pickle.dump((a, b), f1)
f1.close()

f2 = open('temp1.pkl', 'rb')
c, d = pickle.load(f2)
c.append(4)
print(d)

输出:

[1, 2, 3, 4]

由此可见,完美保持了对象之间的引用关系

保持对象的引用关系2

import pickle

a = [1, 2, 3]
b = [4, 5, 6]
a.append(b)
b.append(a)
f = pickle.dumps((a, b))
c, d = pickle.loads(f)
print(c in d, d in c)

输出:

True True

分别pickle无法保持引用关系

分别pickle无法保持引用关系!(重要!)

import pickle

a = [1, 2, 3]
b = [4, 5, 6]
a.append(b)
b.append(a)
f = open('temp3.pkl', 'wb')
pickle.dump(a, f)
pickle.dump(b, f)
f.close()

f1 = open('temp3.pkl', 'rb')
c = pickle.load(f1)
d = pickle.load(f1)
f1.close()
c[2] is d

输出:

False

json

  • 应用广泛,可以在不同语言、前后端之间传输数据。
  • 但是只能序列化 dict
  • 使用方法与 pickle 完全一致
import json

d = {'name': 'Tom', 'age': 20}

json_str = json.dumps(d,ensure_ascii=False)
d1 = json.loads(json_str)

或者存文件

d = {'name': 'Tom', 'age': 20}

# 存到 json 文件
with open('file.json', 'w') as f:
    json_str = json.dump(d, f, ensure_ascii=False, indent=0)
# 不加 indent,所有都放到1行。加了以后更好看。

with open('file.json', 'r') as f:
    d1 = json.load(f)

PickleSerializer

功能与 pickle 类似

准备你的模型

from sklearn import linear_model

lm=linear_model.LinearRegression()
x=np.random.rand(1000,1)
y=x+0.1*np.random.rand(1000,1)
lm.fit(x,y)

模型转为文本

from pyspark import PickleSerializer
ps=PickleSerializer()
model_str=ps.dumps(obj=lm)
# 是一个 byte 类型的数据,然后可以存到hive了
# 存hive略,要先用 str(model_str) 转为str,然后存hive
# 从hive读取时,用 eval() 转回 Byte 格式

文本转模型

from pyspark import PickleSerializer
ps=PickleSerializer()
model_load=ps.loads(model_str)
model_load.predict([[0.1]])

另外

这个可以序列化 iterator,不过还没试过

ps.dump_stream
ps.load_stream

MarshalSerializer:faster than PickleSerializer but supports fewer datatypes

参考资料

python pickle模块


您的支持将鼓励我继续创作!