以下代码可以在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])
,发现在Python2中类型是<type 'file'>
,而在Python3中类型是<class '_io.TextIOWrapper'>
。
我已经检查了这些堆栈溢出问题,但它们都没有对此有帮助的答案:
python 3.5: TypeError: a bytes-like object is required, not 'str' when writing to a file
Python sockets error TypeError: a bytes-like object is required, not 'str' with send function
更新
这里有一堆答案说要将open(fname, 'r')
更改为open(fname, 'rb')
,但这只会导致另一个错误:UnicodeDecodeError: 'ascii' codec can't decode byte 0xc0 in position 0: ordinal not in range(128)
发布于 2018-06-08 15:16:23
引用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]
发布于 2018-06-08 15:16:17
正如pickle.load
方法的documentation所说的(重点是我的):
readline参数文件必须有两个方法,一个接受整数参数的
()方法和一个不需要参数的readline()方法。这两种方法都应该返回字节。
open(stuff, 'r')
将打开文件以读取文本,而不是原始字节。因此,open(stuff, 'r').read
将返回str
,而不是bytes
。要修复此问题,请以二进制模式打开该文件:open(stuff, 'rb')
。
https://stackoverflow.com/questions/50763584
复制相似问题