- 项目之前是python2, 改成python3后,注意以下几点:
- `1. pickle模块`
- `2. 文件加载`
- 2.1 原始代码及错误
- 2.2 第一次修改(无效)
- 2.3 第二次修改(这个语句不报错了,但出现了另一个错误KeyError):
- 2.4 KeyError的根源:bytes与str类型
- 2.5 最后一次修改(成功)
- `小结`
(关键错误类型:UnicodeDecodeError编码错误、KeyError键错误)
1. pickle模块
python2中有cPickle包,python3中直接用pickle包即可
import cPickle as pickle # python2 改为import pickle # python3
2. 文件加载 2.1 原始代码及错误
data = pickle.load(open(self.data_path + self.data_name + '.pk', 'rb'))
- 出现了UnicodeDecodeError: 'ascii' codec can't decode byte 0xeb in position 2: ordinal not in range(128)错误
- (因为pickle模块中的load()方法会将其他数据类型转化为二进制的字节类(bytes),因此,文件的读写方式应该是’wb’和’rb’形式。若读方式不是二进制的形式,则会报错:write() argument must be str, not bytes.所以不能修改’rb’部分)
- 查阅资料,给出的解决方法:需要编码
2.2 第一次修改(无效)
于是我将编码修改为‘utf-8’:
data = pickle.load(open(self.data_path + self.data_name + '.pk', 'rb'), encoding='utf-8')
错误信息:
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 2-3: invalid continuation byte
2.3 第二次修改(这个语句不报错了,但出现了另一个错误KeyError):
想着pickle处理的是bytes类型的数据,因此将编码方式改为bytes:
data = pickle.load(open(self.data_path + self.data_name + '.pk', 'rb'), encoding='bytes')
出现了KeyError: 'vid_list', 查不到data变量(dict类型)的键值
报错语句:self.vid_list = data[‘vid_list’]
2.4 KeyError的根源:bytes与str类型
- 于是我debug,发现有实际上data变量中有vid_list这个键,但其前面有个字符b, 经查阅是bytes类型的数据,而我们源代码语句中 self.vid_list = data[‘vid_list’] 的键值为str类型的数据,所以报错
- (这里其实还是python2和python3的冲突,python2中不区分str类型和bytes类型,而python3中区分str类型和bytes类型,所以原来python2中的bytes类型的键值在python3中无法识别其为字符串str类型)
2.5 最后一次修改(成功)
改变编码类型:
data = pickle.load(open(self.data_path + self.data_name + '.pk', 'rb'), encoding='iso-8859-1')
data变量中的键值变为了str类型:
小结
python2中不区分str类型和bytes类型,而python3中区分str类型和bytes类型,
所以原来python2中的bytes类型的键值在python3中无法识别其为字符串str类型



