加载pickle文件报错:无法在deap.creator获取Individual属性如何解决
错误原因
该报错与操作系统无关,核心是pickle序列化规则限制:pickle存储类实例时仅保存类的引用路径,不会保存类的完整定义。待读取的tradeopt.pars文件中包含DEAP框架动态生成的Individual类实例,反序列化时必须在deap.creator模块下提前注册结构完全一致的Individual类才能正常解析。
现有代码还存在隐藏问题:pickle文件属于二进制文件,必须使用二进制读模式rb打开,当前使用的文本模式r即使解决类匹配问题也会触发编码报错。
修复方案
- 提前在代码开头导入DEAP相关模块,注册和序列化时结构一致的Fitness类、Individual类,参数必须与生成pickle文件时的注册参数完全匹配
- 修改文件打开模式为
rb
修复后完整代码
import os import lzma import pickle import sys from shutil import rmtree from deap import base, creator # 下方注册参数需和生成pickle文件时的参数完全一致,可直接从生成文件的原始代码中复制 creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Individual", list, fitness=creator.FitnessMax) def main(): wk_dir=sys.path[0] loaded_pars,sim_settings=pickle_load(os.path.join(wk_dir,'tradeopt.pars'),'lzma') print(sim_settings) def pickle_load(filePath,compression=None): open_cmd=open if compression is None else __import__(compression).open # 调整为二进制读模式 with open_cmd(filePath,'rb') as f: output=pickle.load(f) return output if __name__ == "__main__": try: main() except KeyboardInterrupt: print ("Ctrl+C pressed. Stopping...")
注意事项
- 若运行后仍然报错,可确认生成
tradeopt.pars的原始代码中creator.create的参数,调整为和原始代码完全一致即可 - 若原始Fitness为多目标优化,需修改
weights参数的元组长度和数值和序列化时一致
内容的提问来源于stack exchange,提问作者Stacey
相关产品推荐
相关产品推荐

