类内定义数据类,使用pickle序列化对象列表触发AttributeError求助
问题分析与解决方案
错误原因
pickle序列化对象时,要求对象所属的类必须是模块级别的可全局访问类。你将CellClass定义在Mod类内部,它属于Mod的局部类,pickle无法通过全局命名空间找到这个类的定义,因此抛出AttributeError: Can't pickle local object 'Mod.__init__.<locals>.CellClass'。之前在类外正常运行,是因为类处于模块顶层,pickle能通过模块名+类名定位到它。
修复方案
方案1:将CellClass移至模块级别(推荐)
把CellClass从Mod类内部移出,作为模块的顶层类,让pickle能正常识别它:
from dataclasses import dataclass import pickle # 模块级别定义数据类 @dataclass(slots=True) class CellClass: fgcolor: str bgcolor: str text: str status: str class Mod: CellContentList = [] def InitializeCellContentList(self): # 修正循环内的append位置,原代码只会添加最后一个元素 for x in range(20): newitem = CellClass(fgcolor="black", bgcolor="lightgrey", text="", status="unlocked") self.CellContentList.append(newitem) def WriteCellData(self): with open('CellData.pkl', 'wb') as file: pickle.dump(self.CellContentList, file)
方案2:局部类自定义序列化逻辑(复杂场景可选)
如果必须保留CellClass在Mod内部,需要给CellClass实现__reduce__方法,手动指定序列化/反序列化的逻辑:
from dataclasses import dataclass import pickle class Mod: @dataclass(slots=True) class CellClass: fgcolor: str bgcolor: str text: str status: str def __reduce__(self): # 返回(构造函数,参数元组),pickle用这个来重建对象 return (Mod.CellClass, (self.fgcolor, self.bgcolor, self.text, self.status)) CellContentList = [] def InitializeCellContentList(self): for x in range(20): newitem = self.CellClass(fgcolor="black", bgcolor="lightgrey", text="", status="unlocked") self.CellContentList.append(newitem) def WriteCellData(self): with open('CellData.pkl', 'wb') as file: pickle.dump(self.CellContentList, file)
额外bug修正
你的InitializeCellContentList函数存在逻辑错误:append语句在循环外部,导致循环结束后仅最后一个newitem被添加到列表。需要将CellContentList.append(newitem)移动到循环内部,才能生成20个元素的列表。
内容的提问来源于stack exchange,提问作者fmex
相关产品推荐
相关产品推荐

