如何在Python 3.7中正确反序列化Python 2.5生成的Pickle数据
解决Python 3.7反序列化Python 2.5生成Pickle数据的问题
问题根源
- Windows换行符干扰:Python 2.5的
sys.stdout默认是文本模式,在Windows环境下会自动把换行符\n转换成\r\n,导致Pickle数据中混入\r字符,反序列化时被误判为模块名的一部分,引发ModuleNotFoundError: No module named 'test_class\r'。 - 跨版本Pickle兼容性:Python 2和3的Pickle序列化格式存在差异,尤其是字符串编码和默认协议版本的不兼容问题。
解决方案
需要分别修改Python 2.5端的序列化代码,以及Python 3.7端的反序列化代码:
1. 修改Python 2.5的write.py
确保以二进制模式输出Pickle数据,并指定Python 3兼容的协议版本:
import sys import pickle import os import test_class o = test_class.TestClass() # 强制以二进制模式输出,避免Windows下的换行符转换 out = os.fdopen(sys.stdout.fileno(), 'wb') # 指定协议2(Python 2和3都支持的二进制协议) pickle.dump(o, out, protocol=2)
2. 修改Python 3.7的read.py
指定正确的编码以兼容Python 2的Pickle字符串格式:
import sys import pickle import test_class # 从二进制流读取,用latin1编码兼容Python 2的字节字符串 o = pickle.load(sys.stdin.buffer, encoding='latin1') print(f"加载的对象: {o}") print(f"对象属性a的值: {o.a}")
验证命令
执行原管道命令即可正常运行:
c:\Python25\python.exe write.py | C:\Python37\python.exe read.py
内容的提问来源于stack exchange,提问作者Anton Lahti
相关产品推荐
相关产品推荐

