首页 > 解决方案 > 代码在 Python 2 中有效,但在 Python3 中无效 TypeError: a bytes-like object is required, not 'str'

问题描述

以下代码适用于 Python 2.7:

import os
import pickle

modelpath = "models/"

gmm_files = [os.path.join(modelpath,fname) for fname in 
          os.listdir(modelpath) if fname.endswith('.gmm')]

models    = [pickle.load(open(fname,'r')) for fname in gmm_files]

但是,当我在 Python3 中运行代码时,我从最后一行收到以下错误:

TypeError: a bytes-like object is required, not 'str'

为了得到更好的主意,我尝试print([type(open(fname,'r')) for fname in gmm_files])在两个版本中打印,发现在 python 2 中类型是<type 'file'>,而在 Python 3 中类型是<class '_io.TextIOWrapper'>.

我已经检查了这些 stackoverflow 问题,但他们都没有对此有帮助的答案:

python 3.5:TypeError:写入文件时需要一个类似字节的对象,而不是'str'

Python套接字错误TypeError:需要一个类似字节的对象,而不是带有发送功能的'str'

更新

这里的一堆答案说要更改open(fname, 'r')为,open(fname, 'rb')但这只会导致另一个错误:UnicodeDecodeError: 'ascii' codec can't decode byte 0xc0 in position 0: ordinal not in range(128)

标签: pythonpython-3.xpicklepython-2.x

解决方案


参考https://docs.python.org/3.6/library/pickle.html#pickle.load,您传递给的类文件对象pickle.load需要返回二进制数据。默认情况下,文件以文本模式打开,这就是您看到此错误的原因。如果您以二进制模式打开文件(通过添加'b'到模式),一切都应该工作。

例如

models = [pickle.load(open(fname, 'rb')) for fname in gmm_files]

推荐阅读