【Python学习笔记】序列化
文章目录
- 【Python学习笔记】序列化
- 1.python使用pickle序列化数据
- 1.1. 环境准备
- 1.2. 序列化datetime对象
- 1.3. 序列化DataFrame对象
- 1.3.1 json
- 1.3.2 pickle
- 1.4 序列化list列表
- 2. flaskweb接口传输序列化数据
- 2.1. bytes形式传输
- 2.1.1. datetime对象
- 2.1.2. DataFrame对象
- 2.1.3. list列表
- 2.2. json形式传输
- 2.2.1. datetime对象
- 2.2.2. DataFrame对象
- 2.2.3. list列表
- 3. base64
- 4. pickle和json
- 5. 序列化的数据大小变化
- 6. 总结
1.python使用pickle序列化数据
1.1. 环境准备
import pickle
1.2. 序列化datetime对象
import datetime
import pickle
now = datetime.datetime.now()
# 序列化
p_now = pickle.dumps(now)
# 反序列化
re_p_now = pickle.loads(p_now)
print(re_p_now)
1.3. 序列化DataFrame对象
1.3.1 json
import json
import pandas as pd
d1 = {
'x': [1, 2, 3],
'y': [1, 2, 3],
'z': [1, 2, 3]
}
df = pd.DataFrame(d1)
dict_df = df.to_dict()
json_df = json.dumps(dict_df)
print(json_df)
print(type(json_df))
1.3.2 pickle
import pandas as pd
import pickle
d1 = {
'x': [1, 2, 3],
'y': [1, 2, 3],
'z': [1, 2, 3]
}
df = pd.DataFrame(d1)
p_df = pickle.dumps(df)
new_p_df = pickle.loads(p_df)
print(new_p_df)
1.4 序列化list列表
import pandas as pd
import pickle
d1 = {
'x': [1, 2, 3],
'y': [1, 2, 3],
'z': [1, 2, 3]
}
d2 = {
'x': [4, 5, 6],
'y': [4, 5, 6],
'z': [4, 5, 6]
}
df1 = pd.DataFrame(d1)
df2 = pd.DataFrame(d2)
df_list = [df1, df2]
p_df_list = pickle.dumps(df_list)
new_p_df_list = pickle.loads(p_df_list)
print(type(new_p_df_list))
for e in new_p_df_list:
print(e)
2. flaskweb接口传输序列化数据
2.1. bytes形式传输
2.1.1. datetime对象
import datetime
import pickle
import requests
now = datetime.datetime.now()
# 序列化
p_now = pickle.dumps(now)
url = 'http://127.0.0.1:8023/test'
headers = {'Content-Type': 'application/json'}
r = requests.post(url, data=p_now, headers=headers)
print(r.text)
print(r.status_code)
import base64
import pickle
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
# 从data中接收bytes数据
data = request.data
print(data)
now = pickle.loads(data)
print(now)
return jsonify({"status": "success"}), 200
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8023, debug=True)
2.1.2. DataFrame对象
import pandas as pd
import pickle
import requests
d1 = {
'x': [1, 2, 3],
'y': [1, 2, 3],
'z': [1, 2, 3]
}
df = pd.DataFrame(d1)
p_df = pickle.dumps(df)
headers = {'Content-Type': 'application/json'}
url = 'http://127.0.0.1:8023/test'
r = requests.post(url, data=p_df, headers=headers)
print(r.text)
print(r.status_code)
import pickle
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
# data = request.json['data']
# decode = base64.b64decode(data)
# decode_now = pickle.loads(decode)
# print(decode_now)
data = request.data
print(data)
df = pickle.loads(data)
print(df)
return jsonify({"status": "success"}), 200
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8023, debug=True)
2.1.3. list列表
import datetime
import pandas as pd
import pickle
import requests
d1 = {
'x': [1, 2, 3],
'y': [1, 2, 3],
'z': [1, 2, 3]
}
d2 = {
'x': [4, 5, 6],
'y': [4, 5, 6],
'z': [4, 5, 6]
}
now = datetime.datetime.now()
df1 = pd.DataFrame(d1)
df2 = pd.DataFrame(d2)
df_list = [now, df1, df2]
p_df_list = pickle.dumps(df_list)
headers = {'Content-Type': 'application/json'}
url = "http://127.0.0.1:8023/test"
r = requests.post(url, data=p_df_list, headers=headers)
print(r.status_code)
print(r.text)
import pickle
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
# data = request.json['data']
# decode = base64.b64decode(data)
# decode_now = pickle.loads(decode)
# print(decode_now)
data = request.data
print(data)
data_list = pickle.loads(data)
for e in data_list:
print(e)
return jsonify({"status": "success"}), 200
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8023, debug=True)
2.2. json形式传输
2.2.1. datetime对象
import base64
import datetime
import pickle
import requests
now = datetime.datetime.now()
p_now = pickle.dumps(now) # bytes
encode_now = base64.b64encode(p_now).decode('utf-8') # str
# json不直接支持字节数组 (bytes) 类型。
data = {
'data': encode_now
}
headers = {'Content-Type': 'application/json'}
url = 'http://127.0.0.1:8023/test'
r = requests.post(url, json=data, headers=headers)
print(r.status_code)
print(r.text)
import base64
import pickle
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
# 从json中接收数据
data = request.json['data']
print(data)
decode = base64.b64decode(data)
print(decode)
decode_now = pickle.loads(decode)
print(decode_now)
return jsonify({"status": "success"}), 200
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8023, debug=True)
2.2.2. DataFrame对象
import base64
import pandas as pd
import pickle
import requests
d1 = {
'x': [1, 2, 3],
'y': [1, 2, 3],
'z': [1, 2, 3]
}
df = pd.DataFrame(d1)
p_df = pickle.dumps(df)
encode_df = base64.b64encode(p_df).decode('utf-8')
data = {
'data': encode_df
}
headers = {'Content-Type': 'application/json'}
url = 'http://127.0.0.1:8023/test'
r = requests.post(url, json=data, headers=headers)
print(r.text)
print(r.status_code)
import base64
import pickle
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
data = request.json['data']
print(data)
decode = base64.b64decode(data)
print(decode)
decode_now = pickle.loads(decode)
print(decode_now)
return jsonify({"status": "success"}), 200
2.2.3. list列表
import base64
import datetime
import pandas as pd
import pickle
import requests
d1 = {
'x': [1, 2, 3],
'y': [1, 2, 3],
'z': [1, 2, 3]
}
d2 = {
'x': [4, 5, 6],
'y': [4, 5, 6],
'z': [4, 5, 6]
}
now = datetime.datetime.now()
df1 = pd.DataFrame(d1)
df2 = pd.DataFrame(d2)
df_list = [now, df1, df2]
p_df_list = pickle.dumps(df_list)
encode_list = base64.b64encode(p_df_list).decode('utf-8')
headers = {'Content-Type': 'application/json'}
url = "http://127.0.0.1:8023/test"
data = {
'data': encode_list
}
r = requests.post(url, json=data, headers=headers)
print(r.status_code)
print(r.text)
import base64
import pickle
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
data = request.json['data']
print(data)
decode = base64.b64decode(data)
print(decode)
decode_now = pickle.loads(decode)
for e in decode_now:
print(e)
return jsonify({"status": "success"}), 200
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8023, debug=True)
3. base64
Base64 是一种将二进制数据编码为文本字符串的方式。它通常用于在需要通过文本协议(如电子邮件和HTTP)传输二进制数据时使用。Base64 可以编码任何形式的二进制数据,包括但不限于以下类型:
- 文件数据:任意类型的文件(例如,图像、音频、视频、文档等)都可以编码为Base64字符串。
- 对象数据:通过序列化(如使用
pickle
或json
序列化)将对象转换为字节数组,然后对这些字节数组进行Base64编码。 - 文本数据:虽然文本数据本身是字符串形式,但也可以进行Base64编码以确保其兼容性或加密性。
4. pickle和json
pickle
和 json
是 Python 中常用的两种序列化和反序列化数据的方式。它们各有优缺点,适用于不同的场景。以下是它们的主要区别:
- 序列化和反序列化的对象类型
- pickle:
- 可以序列化和反序列化几乎所有的 Python 对象,包括复杂的对象,如类实例、自定义对象等。
- 序列化后的数据是二进制格式,因此适合于处理任意的 Python 数据结构。
- json:
- 只能序列化和反序列化基本数据类型,如字典、列表、字符串、数字、布尔值和
None
。 - 序列化后的数据是文本格式,因此适合于与其他编程语言和系统进行数据交换。
- JSON 数据格式是标准化的,广泛用于 Web 开发和API通信。
- 只能序列化和反序列化基本数据类型,如字典、列表、字符串、数字、布尔值和
- pickle:
- 数据格式
- pickle:
- 二进制格式,不适合阅读。
- 适合于在 Python 内部使用或在 Python 应用程序之间传输数据。
- json:
- 文本格式,易于阅读和调试。
- 适合于 Web 开发、配置文件和跨语言的数据交换。
- pickle:
- 安全性
- pickle:
- 存在安全隐患,可能会执行任意代码。因此,不要反序列化不受信任的数据。
- 只适合在受信任的环境中使用。
- json:
- 更加安全,因为它仅限于基本数据类型,不会执行任意代码。
- 适合在不受信任的环境中使用。
- pickle:
- 性能
- pickle:
- 对于复杂数据结构,
pickle
通常比json
更快,因为它直接处理二进制数据。 - 适用于需要高效序列化和反序列化的大量数据的场景。
- 对于复杂数据结构,
- json:
- 由于其文本格式,性能可能会稍慢,但由于其广泛兼容性和易用性,通常性能是可以接受的。
- 适用于需要与外部系统或前端进行数据交换的场景。
- pickle:
- 跨语言兼容性
- pickle:
- 专为 Python 设计,不适合与其他编程语言交互。
- 适合于在 Python 程序之间传输数据。
- json:
- 是一种标准的文本格式,支持几乎所有编程语言。
- 适合于跨语言的数据交换。
- pickle:
5. 序列化的数据大小变化
import pandas as pd
import pickle
df = pd.read_csv('2041208842560.csv')
p_df = pickle.dumps(df)
with open('test05', 'wb') as f:
f.write(p_df)
文件大小从20.8MB—>16.5MB
6. 总结
- 使用
pickle
当你需要序列化复杂的 Python 对象,且数据只在受信任的 Python 环境中传输。 - 使用
json
当你需要与其他系统(如前端、数据库、非Python语言)进行数据交换,或者需要人类可读的数据格式。