[英]Code works in Python 2 but not Python3 TypeError: a bytes-like object is required, not 'str'
The following code works in Python 2.7: 以下代码适用于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]
However, when I run the code in Python3, I get the following error from the last line: 但是,当我在Python3中运行代码时,我从最后一行得到以下错误:
TypeError: a bytes-like object is required, not 'str'
In order to get a better idea, I tried printing print([type(open(fname,'r')) for fname in gmm_files])
in both versions and found out that in python 2 the type is <type 'file'>
and in Python 3 the type is <class '_io.TextIOWrapper'>
. 为了获得更好的想法,我尝试在两个版本中打印print([type(open(fname,'r')) for fname in gmm_files])
现在python 2中类型是<type 'file'>
print([type(open(fname,'r')) for fname in gmm_files])
<type 'file'>
在Python 3中,类型是<class '_io.TextIOWrapper'>
。
I've checked out these stackoverflow questions but neither of them have helpful answers for this: 我已经检查了这些stackoverflow问题,但他们都没有对此有用的答案:
python 3.5: TypeError: a bytes-like object is required, not 'str' when writing to a file python 3.5:TypeError:需要一个类似字节的对象,而不是写入文件时的'str'
Python sockets error TypeError: a bytes-like object is required, not 'str' with send function Python套接字错误TypeError:需要一个类似字节的对象,而不是带有send函数的'str'
UPDATE UPDATE
A bunch of the answers here said to change open(fname, 'r')
to open(fname, 'rb')
but that just leads to another error: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc0 in position 0: ordinal not in range(128)
这里的一堆答案说改为open(fname, 'r')
open(fname, 'rb')
但这只会导致另一个错误: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc0 in position 0: ordinal not in range(128)
Ref https://docs.python.org/3.6/library/pickle.html#pickle.load , the file-like object you pass to pickle.load
needs to return binary data. 参考https://docs.python.org/3.6/library/pickle.html#pickle.load ,传递给pickle.load
的类文件对象需要返回二进制数据。 Files are opened in text-mode by default, which is why you're seeing this error. 默认情况下,文件以文本模式打开,这就是您看到此错误的原因。 If you open the file in binary mode (by adding 'b'
to the mode), everything should be work. 如果以二进制模式打开文件(通过在模式中添加'b'
),一切都应该有效。
Eg 例如
models = [pickle.load(open(fname, 'rb')) for fname in gmm_files]
As the documentation for the pickle.load
method says (emphasis mine): 正如pickle.load
方法的文档所说(强调我的):
The argument file must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. 参数文件必须有两个方法,一个采用整数参数的read()方法和一个不需要参数的readline()方法。 Both methods should return bytes. 两种方法都应返回字节。
open(stuff, 'r')
will open the file for reading text , not raw bytes. open(stuff, 'r')
将打开文件以读取文本 ,而不是原始字节。 Thus, open(stuff, 'r').read
will return str
, not bytes
. 因此, open(stuff, 'r').read
将返回str
,而不是bytes
。 To fix that, open the file in binary mode: open(stuff, 'rb')
. 要解决此问题,请以二进制模式打开文件: open(stuff, 'rb')
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.