You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何高效存储类实例到文本文件并解决反序列化与换行问题

问题1:实现自定义类实例的持久化存储与读取

你当前直接存储构造函数字符串或者str(实例)的方式都无法直接还原为实例,可选择以下两种方案解决:

  • 方案1:基于序列化+base64编码适配文本存储(推荐,兼容性好)
    用Python内置的pickle模块序列化实例,再转成base64字符串写入文本,读取时反向操作即可,示例代码:
    import pickle, base64
    
    # 写入时的处理
    if "MAINWEAPON" not in inv or inv["MAINWEAPON"] == "":
        # 直接存实例,不要转字符串
        inv["MAINWEAPON"] = Weapon(sw, 0, Ability(0, "0"), [f"{name}'s first weapon."], dmg=30, cc=20, str=15)
    # 序列化字典并转成文本可存储的字符串
    ser_inv = base64.b64encode(pickle.dumps(inv)).decode('utf-8')
    lines[1] = ser_inv + '\n' # 注意换行处理
    
    # 读取时的处理
    ser_inv = lines[1].strip()
    inv = pickle.loads(base64.b64decode(ser_inv))
    # 此时inv["MAINWEAPON"]就是Weapon类实例
    
    注意:pickle仅可用于读取你自己生成的可信内容,不要加载未知来源的序列化文件。
  • 方案2:基于__repr__ + 实例重建(适合小项目轻量使用)
    给Weapon、Ability类实现__repr__方法,返回可直接重建实例的构造代码,示例:
    class Ability:
        # 原有代码省略
        def __repr__(self):
            return f"Ability({self.param1}, {repr(self.param2)})" # 按你实际的属性调整
    
    class Weapon:
        # 原有代码省略
        def __repr__(self):
            return f"Weapon({repr(self.sw)}, {self.level}, {repr(self.ability)}, {repr(self.desc)}, dmg={self.dmg}, cc={self.cc}, str={self.str})"
    
    写入时用repr(inv)代替str(inv),读取时用ast.literal_eval(需提前导入ast模块)还原字典即可。

问题2:文件行数减少的原因与修复

错误原因

  1. readlines()读取到的每一行默认自带换行符\n,你给lines[1]强制拼接\n时,如果原文件的换行符是\r\n(Windows系统)或\r(老Mac系统),默认r模式不会统一识别换行符,可能导致行合并,最终行数减少。
  2. 没有提前判断读取到的lines长度,如果读文件异常导致lines长度小于2,后续写入会直接丢失末尾行。

修复代码

# 打开文件时指定newline参数统一识别所有换行格式
with open(memorypath(), "r", encoding='utf-8', newline='') as f:
    lines = f.readlines()
inv = inventory()
if "MAINWEAPON" not in inv or inv["MAINWEAPON"] == "":
    inv["MAINWEAPON"] = Weapon(sw, 0, Ability(0, "0"), [f"{name}'s first weapon."], dmg=30, cc=20, str=15)

# 先判断lines长度,避免索引越界,再处理换行
ser_inv = base64.b64encode(pickle.dumps(inv)).decode('utf-8')
if len(lines) >= 2:
    # 统一处理换行,保留原行的换行规则,避免额外新增/丢失换行
    lines[1] = ser_inv + lines[1][len(lines[1].rstrip('\r\n')):]
else:
    # 行数不足时补空行到至少2行
    while len(lines) < 2:
        lines.append('\n')
    lines[1] = ser_inv + '\n'

# 写入时也指定newline参数,避免换行符自动转换
with open(memorypath(), "w", encoding='utf-8', newline='') as f:
    f.writelines(lines)

内容的提问来源于stack exchange,提问作者Gamer 13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 06:24:03