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

Python使用pickle操作二进制文件报unpickling stack underflow错误如何解决

错误原因

你遇到的_pickle.UnpicklingError: unpickling stack underflow错误根本原因是pickle序列化后的内容是变长的,你在Update函数中直接原地覆盖记录的逻辑存在缺陷:

  • 每次pickle.dump()写入的字节长度由内容决定,不是固定值
  • 当你修改记录后重新dump,如果新序列化的字节长度大于原位置的原有字节长度,就会覆盖下一条记录的头部内容,导致下一条记录变成不完整的pickle块,后续读取时就会抛出栈下溢错误
  • 不同运行环境表现不同是因为测试时输入的内容长度有差异:PyCharm中测试时更新后的记录序列化长度刚好小于等于原长度,没有破坏后续记录;IDLE中测试时更新后的内容更长,破坏了后续记录结构,因此触发错误
修复方案

推荐使用「全量读取-内存修改-全量写回」的逻辑实现更新,完全规避变长序列化的原地写入问题,修改后的完整代码如下:

import pickle
def Write():
    f=open("StudentDetails.dat",'wb')
    while True:
        r=int(input("Enter Roll no.: "))
        n=input("Enter Name: ")
        m=int(input("Enter Marks: "))
        record=[r,n,m]
        pickle.dump(record,f)
        ch=input("Do you want to enter more records (Y/N)")
        if ch in 'Nn':
            break
    f.close()

def Read():
    f=open("StudentDetails.dat",'rb')
    try:
        while True:
            rec=pickle.load(f)
            print(rec)
    except EOFError:
        pass
    f.close()
    
def Update():
    # 先读所有记录到内存
    records = []
    f=open("StudentDetails.dat",'rb')
    try:
        while True:
            records.append(pickle.load(f))
    except EOFError:
        pass
    f.close()
    # 内存中修改对应记录
    rollno=int(input("Enter roll no whose marks you want to update: "))
    updated = False
    for rec in records:
        if rec[0] == rollno:
            um=int(input("Enter updated marks: "))
            rec[2] = um
            updated = True
            break
    if not updated:
        print("未找到对应学号的记录")
        return
    # 全量写回文件
    f=open("StudentDetails.dat",'wb')
    for rec in records:
        pickle.dump(rec, f)
    f.close()
    
Write()
Read()
Update()
Read()
补充说明

如果你的学生记录量级非常大,不适合全量读入内存,可以改用固定长度的二进制存储格式(比如struct库序列化),才能安全实现原地更新操作。

内容的提问来源于stack exchange,提问作者Anshul Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:24:01