全文一览
- 一、前言
- 1.1 需求分析
- 1.2 准备工作
- 二、方法合集
- 2.1 txt 方法
- 2.1.1 保存变量
- 2.1.2 加载 txt 文件
- 2.1.3 验证变量
- 2.1.4 txt 文件样式
- 2.2 json 方法
- 2.2.1 保存变量
- 2.2.2 加载 json 文件
- 2.2.3 提取变量
- 2.2.4 json 文件样式
- 2.3 joblib 方法
- 2.3.1 保存变量
- 2.3.2 加载 joblib 文件
- 2.3.3 提取变量
- 2.3.4 joblib 文件样式
- 2.4 pickle 方法
- 2.4.1 保存变量
- 2.4.2 加载 pkl 文件
- 2.4.3 提取变量
- 2.4.4 pkl 文件样式
- 三、运行截图
- 四、完整代码
一、前言
1.1 需求分析
python 代码在执行完毕后,会回收全部的变量。要重新获得其中的中间变量,重复运行代码即可解决该问题。
但是,如果目标是对中间变量进行分析处理,这样会使得代码冗杂。一些场景下,执行代码还会花费大量的时间。随机数的引入还可能使得每次复现的结果不同。
因而,本文就如何保存代码执行过程中的中间变量,对 txt、json、joblib 以及 pickle方法进行了探究。
1.2 准备工作
为了验证这些方法的效果,本文先通过 random 方法获取一些随机变量 x 和 y 。由于 json 、joblib 和 pickle 文件中只能存储一个变量,本文还创建了 Variables 字典变量,用于间接存储变量 x 和 y 。
import random
x = [random.random() for _ in range(5)]
y = [random.randint(1,10) for _ in range(5)]
Variables = {"x": x, "y": y}
print("原先的全部变量:", Variables)
此外,joblib 库属于第三方库,并非 python 自带,在使用前需要安装:
>pip install joblib
二、方法合集
2.1 txt 方法
提到保存,首先最容易被想到的就是 txt 文件。该方法能够简洁快速地保存字符串。
2.1.1 保存变量
首先,将变量保存到 txt 文件。该方法需要将 x 和 y 转化为字符串。由于该方式读取往往通过行数来区分不同的变量,故而,需要在 x 和 y 字符串中间插入换行符“\n”。
# 将变量保存到 txt 文件中
with open("variables.txt", 'w', encoding="utf-8") as f:
f.write(str(x))
f.write("\n")
f.write(str(y))
2.1.2 加载 txt 文件
其次,按行读取变量。通过 readline 可以获得每一行的字符串,再通过 eval 函数,即可将字符串转化回变量。
# 从 txt 文件中加载变量
with open("variables.txt", 'r', encoding="utf-8") as f:
x_str = f.readline()
y_str = f.readline()
x_loaded = eval(x_str)
y_loaded = eval(y_str)
2.1.3 验证变量
最后,验证变量。通过 == 符号,验证保存的变量是否与原先的变量一致。
# 验证
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
# x 加载前后一致: True
# y 加载前后一致: True
2.1.4 txt 文件样式
txt 文件内容如下:
虽然本方法较为简单,但需要明确行与变量的对应关系。此外,对于复杂的对象,如自定义的类、训练的深度学习模型等,该方法的保存较为困难。
2.2 json 方法
2.2.1 保存变量
json 也是文件保存常用的方法,跟 txt 一样可以跨平台实现数据交互。json 的兼容性和效率要更高。
首先,保存变量到 json 文件。该文件以“json”为后缀,可以指定编码格式。此处,dump 传入的 f 为文件对象。
# 将变量保存到 json 文件中
with open("variables.json", "w", encoding="utf-8") as f:
json.dump(Variables, f)
2.2.2 加载 json 文件
其次,从 json 文件中加载变量。load 传入的为文件对象。
# 从 json 文件中加载变量
with open("variables.json", "r", encoding="utf-8") as f:
Variables_loaded = json.load(f)
print("加载出的全部变量:", Variables)
2.2.3 提取变量
最后,获取对应变量并验证。
# 验证
x_loaded = Variables_loaded['x']
y_loaded = Variables_loaded['y']
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
print("全部变量加载前后一致:", Variables_loaded == Variables)
2.2.4 json 文件样式
该方法文件中仅保存一个变量,共占一行。类似 txt,该方法在面对复杂对象时,序列化能力较差。
将该行内容复制,到 json 解析等网站上可以快速解析。
2.3 joblib 方法
joblib 用于高效地序列化和反序列化 Python 对象。其以特定的二进制格式保存变量,使用方法较为简单,在科学计算、机器学习和数据处理等领域中被广泛使用。
2.3.1 保存变量
首先,保存变量到 joblib 文件。使用 dump 方法,直接将变量保存到对应名称的文件中。文件以“joblib”为后缀。注意:这里使用的是文件名,而非文件对象。
# 将变量保存到 joblib 文件中
joblib.dump(Variables, 'variables.joblib')
2.3.2 加载 joblib 文件
其次,加载 joblib 文件。此处也是直接使用文件名。
# 从 joblib 文件中加载变量
Variables_loaded = joblib.load('variables.joblib')
print("加载出的全部变量:", Variables)
2.3.3 提取变量
最后,从字典中获取多个变量并验证。
# 验证
x_loaded = Variables_loaded['x']
y_loaded = Variables_loaded['y']
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
print("全部变量加载前后一致:", Variables_loaded == Variables)
2.3.4 joblib 文件样式
joblib 方法保存的文件为二进制格式,不能直接阅读。
2.4 pickle 方法
pickle 是 python 自带的一种序列化库。该方法支持对所有 python 对象的序列化存储,使用二进制进行保存和读取。
2.4.1 保存变量
首先,保存到 pkl 文件。写入时采用“wb”方法,以二进制的形式写入。pickle 文件的后缀为“pkl”。在 dump 中传入的 f 为文件对象,而非文件名,因此常配合 with-open-as 语句一起使用。
# 将变量保存到 pkl 文件中
with open("variables.pkl", "wb") as f:
pickle.dump(Variables, f)
2.4.2 加载 pkl 文件
其次,从 pkl 文件中加载变量。采用“rb”二进制方法读取。load 参数为文件对象,返回结果为对应的变量。
# 从 pkl 文件中加载变量
with open("variables.pkl", "rb") as f:
Variables_loaded = pickle.load(f)
print("加载出的全部变量:", Variables)
2.4.3 提取变量
最后,抽取变量并验证。
# 验证
x_loaded = Variables_loaded['x']
y_loaded = Variables_loaded['y']
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
print("全部变量加载前后一致:", Variables_loaded == Variables)
2.4.4 pkl 文件样式
类似于 joblib,由于使用二进制进行存储,一般 pkl 文件内容不能直接观察到:
三、运行截图
四、完整代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName : variables_save_load.py
# @Time : 2024/4/21 0:14
# @Author : Carl.Zhang
# Function : save
import json
import pickle
import joblib
import random
x = [random.random() for _ in range(5)]
y = [random.randint(1,10) for _ in range(5)]
Variables = {"x": x, "y": y}
print("原先的全部变量:", Variables)
def method_txt():
# txt
print("\ntxt method:")
# 将变量保存到 txt 文件中
with open("variables.txt", 'w', encoding="utf-8") as f:
f.write(str(x))
f.write("\n")
f.write(str(y))
# 从 txt 文件中加载变量
with open("variables.txt", 'r', encoding="utf-8") as f:
x_str = f.readline()
y_str = f.readline()
x_loaded = eval(x_str)
y_loaded = eval(y_str)
# 验证
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
def method_json():
# json
print("\njson method:")
# 将变量保存到 json 文件中
with open("variables.json", "w", encoding="utf-8") as f:
json.dump(Variables, f)
# 从 json 文件中加载变量
with open("variables.json", "r", encoding="utf-8") as f:
Variables_loaded = json.load(f)
print("加载出的全部变量:", Variables)
# 验证
x_loaded = Variables_loaded['x']
y_loaded = Variables_loaded['y']
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
print("全部变量加载前后一致:", Variables_loaded == Variables)
def method_joblib():
# joblib
print("\njoblib method:")
# 将变量保存到 joblib 文件中
joblib.dump(Variables, 'variables.joblib')
# 从 joblib 文件中加载变量
Variables_loaded = joblib.load('variables.joblib')
print("加载出的全部变量:", Variables)
# 验证
x_loaded = Variables_loaded['x']
y_loaded = Variables_loaded['y']
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
print("全部变量加载前后一致:", Variables_loaded == Variables)
def method_pickle():
# pickle
print("\npickle method:")
# 将变量保存到 pkl 文件中
with open("variables.pkl", "wb") as f:
pickle.dump(Variables, f)
# 从 pkl 文件中加载变量
with open("variables.pkl", "rb") as f:
Variables_loaded = pickle.load(f)
print("加载出的全部变量:", Variables)
# 验证
x_loaded = Variables_loaded['x']
y_loaded = Variables_loaded['y']
print("x 加载前后一致:", x_loaded == x)
print("y 加载前后一致:", y_loaded == y)
print("全部变量加载前后一致:", Variables_loaded == Variables)
if __name__ == '__main__':
method_txt()
method_json()
method_joblib()
method_pickle()
更多 python 的使用方法和应用,敬请关注后续更新~