【Python学习笔记】序列化

【Python学习笔记】序列化

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 可以编码任何形式的二进制数据,包括但不限于以下类型:

  1. 文件数据:任意类型的文件(例如,图像、音频、视频、文档等)都可以编码为Base64字符串。
  2. 对象数据:通过序列化(如使用 picklejson 序列化)将对象转换为字节数组,然后对这些字节数组进行Base64编码。
  3. 文本数据:虽然文本数据本身是字符串形式,但也可以进行Base64编码以确保其兼容性或加密性。

4. pickle和json

picklejson 是 Python 中常用的两种序列化和反序列化数据的方式。它们各有优缺点,适用于不同的场景。以下是它们的主要区别:

  1. 序列化和反序列化的对象类型
    1. pickle:
      • 可以序列化和反序列化几乎所有的 Python 对象,包括复杂的对象,如类实例、自定义对象等。
      • 序列化后的数据是二进制格式,因此适合于处理任意的 Python 数据结构。
    2. json:
      • 只能序列化和反序列化基本数据类型,如字典、列表、字符串、数字、布尔值和 None
      • 序列化后的数据是文本格式,因此适合于与其他编程语言和系统进行数据交换。
      • JSON 数据格式是标准化的,广泛用于 Web 开发和API通信。
  2. 数据格式
    1. pickle:
      • 二进制格式,不适合阅读。
      • 适合于在 Python 内部使用或在 Python 应用程序之间传输数据。
    2. json:
      • 文本格式,易于阅读和调试。
      • 适合于 Web 开发、配置文件和跨语言的数据交换。
  3. 安全性
    1. pickle:
      • 存在安全隐患,可能会执行任意代码。因此,不要反序列化不受信任的数据。
      • 只适合在受信任的环境中使用。
    2. json:
      • 更加安全,因为它仅限于基本数据类型,不会执行任意代码。
      • 适合在不受信任的环境中使用。
  4. 性能
    1. pickle:
      • 对于复杂数据结构,pickle 通常比 json 更快,因为它直接处理二进制数据。
      • 适用于需要高效序列化和反序列化的大量数据的场景。
    2. json:
      • 由于其文本格式,性能可能会稍慢,但由于其广泛兼容性和易用性,通常性能是可以接受的。
      • 适用于需要与外部系统或前端进行数据交换的场景。
  5. 跨语言兼容性
    1. pickle:
      • 专为 Python 设计,不适合与其他编程语言交互。
      • 适合于在 Python 程序之间传输数据。
    2. json:
      • 是一种标准的文本格式,支持几乎所有编程语言。
      • 适合于跨语言的数据交换。

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. 总结

  1. 使用 pickle 当你需要序列化复杂的 Python 对象,且数据只在受信任的 Python 环境中传输。
  2. 使用 json 当你需要与其他系统(如前端、数据库、非Python语言)进行数据交换,或者需要人类可读的数据格式。
  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值