如何跨类赋值变量并持久化,避免重复执行耗时操作?
解决持久化数据的方案
这问题我熟!核心思路就是把爬取到的scores数据持久化存储到本地文件,下次运行直接读文件就行,不用再跑耗时的Selenium爬取流程。给你两种常用的实现方案,按需挑:
方案一:用Pickle(适合Python原生对象)
Pickle是Python自带的序列化工具,能直接保存defaultdict这类Python特有的对象,不用额外转换,非常省心。
修改后的Test类代码如下:
import pickle import os from collections import defaultdict from data import AllData # 假设你的AllData类在data.py中 class Test: def __init__(self): # 定义缓存文件的路径,你可以根据项目结构调整 self.cache_file = "scores_cache.pkl" if os.path.exists(self.cache_file): # 本地有缓存,直接加载数据 with open(self.cache_file, "rb") as f: self.numbers = pickle.load(f) print("✅ 已从本地缓存加载数据,跳过爬取") else: # 无缓存,执行爬取并保存 print("⚠️ 本地无缓存,开始执行爬取...") data = AllData() self.numbers = data.scores # 把数据写入缓存文件 with open(self.cache_file, "wb") as f: pickle.dump(self.numbers, f) print("✅ 爬取完成,数据已保存到本地缓存")
方案优势:
- 无需转换数据格式,直接保存/加载Python原生对象(比如
defaultdict) - 序列化速度快,文件体积相对小
注意点:
- 缓存文件是二进制格式,人类无法直接读取内容
- 只能用Python加载该文件,跨语言不兼容
方案二:用JSON(可读性强,跨语言兼容)
如果需要缓存文件可读,或者要和其他语言交互,JSON是更好的选择。但要注意:JSON不支持defaultdict这类特殊对象,需要先转换成普通字典再保存。
修改后的Test类代码如下:
import json import os from collections import defaultdict from data import AllData class Test: def __init__(self): self.cache_file = "scores_cache.json" if os.path.exists(self.cache_file): # 加载JSON缓存 with open(self.cache_file, "r", encoding="utf-8") as f: saved_data = json.load(f) # 如果原数据是defaultdict,转成原来的类型(这里假设是list类型的defaultdict) self.numbers = defaultdict(list, saved_data) print("✅ 已从本地缓存加载数据") else: print("⚠️ 本地无缓存,开始执行爬取...") data = AllData() self.numbers = data.scores # 把defaultdict转成普通字典才能存入JSON saved_data = dict(self.numbers) with open(self.cache_file, "w", encoding="utf-8") as f: json.dump(saved_data, f, indent=4) # indent=4让文件更易读 print("✅ 爬取完成,数据已保存到本地缓存")
方案优势:
- 缓存文件是纯文本格式,直接用编辑器就能查看内容
- 跨语言兼容,其他编程语言也能读取该文件
注意点:
- 必须把Python特有对象(比如
defaultdict)转换成JSON支持的类型(字典、列表、字符串等) - 对于复杂对象,序列化/反序列化需要额外处理
额外优化建议
如果爬取的内容可能会更新,你可以给缓存加个有效期判断,比如:
import time # 在判断文件存在后,检查文件修改时间是否超过7天 file_mtime = os.path.getmtime(self.cache_file) if time.time() - file_mtime > 7 * 24 * 3600: # 缓存过期,重新爬取并覆盖缓存 print("⚠️ 缓存已过期,重新爬取数据...") data = AllData() self.numbers = data.scores # 重新保存缓存(代码和之前一致)
内容的提问来源于stack exchange,提问作者dmo2412
相关产品推荐
相关产品推荐

