I've very recently migrated to Py 3.5.This code was working properly in Python 2.7:
我最近迁移到Py 3.5。这段代码在Python 2.7中正常工作:
with open(fname, 'rb') as f: lines = [x.strip() for x in f.readlines()]for line in lines: tmp = line.strip().lower() if 'some-pattern' in tmp: continue # ... code
After upgrading to 3.5, I'm getting the:
升级到3.5后,我得到了:
TypeError: a bytes-like object is required, not 'str'
error on the last line (the pattern search code).
最后一行的错误(模式搜索代码)。
I've tried using the .decode()
function on either side of the statement, also tried:
我尝试在语句的任一侧使用.decode()函数,也尝试过:
if tmp.find('some-pattern') != -1: continue
- to no avail.
- 无济于事。
I was able to resolve almost all 2:3 issues quickly, but this little statement is bugging me.
我能够迅速解决几乎所有2:3的问题,但这个小小的陈述让我烦恼。
7 个解决方案
#1
268
You opened the file in binary mode:
您以二进制模式打开文件:
with open(fname, 'rb') as f:
This means that all data read from the file is returned as bytes
objects, not str
. You cannot then use a string in a containment test:
这意味着从文件读取的所有数据都作为字节对象返回,而不是str。然后,您无法在包含测试中使用字符串:
if 'some-pattern' in tmp: continue
You'd have to use a bytes
object to test against tmp
instead:
您必须使用bytes对象来测试tmp:
if b'some-pattern' in tmp: continue
or open the file as a textfile instead by replacing the 'rb'
mode with 'r'
.
或者将文件作为文本文件打开,而不是将'rb'模式替换为'r'。
#2
59
You can encode your string by using .encode()
您可以使用.encode()对字符串进行编码
Example:
例:
'Hello World'.encode()
#3
20
Like it has been already mentioned, you are reading the file in binary mode and then creating a list of bytes. In your following for loop you are comparing string to bytes and that is where the code is failing.
就像已经提到过的那样,您正在以二进制模式读取文件,然后创建一个字节列表。在您的以下for循环中,您将比较字符串与字节,这是代码失败的地方。
Decoding the bytes while adding to the list should work. The changed code should look as follows:
添加到列表时解码字节应该有效。更改的代码应如下所示:
with open(fname, 'rb') as f: lines = [x.decode('utf8').strip() for x in f.readlines()]
The bytes type was introduced in Python 3 and that is why your code worked in Python 2. In Python 2 there was no data type for bytes:
字节类型是在Python 3中引入的,这就是为什么你的代码在Python 2中工作的原因。在Python 2中,没有字节的数据类型:
>>> s=bytes('hello')>>> type(s)<type 'str'>
#4
9
for this small example: import socket
对于这个小例子:import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)mysock.connect(('www.py4inf.com', 80))mysock.send(**b**'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')while True: data = mysock.recv(512) if ( len(data) < 1 ) : break print (data);mysock.close()
adding the "b" before 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n'solved my problem
在'GET http://www.py4inf.com/code/romeo.txt之前添加“b”HTTP / 1.0 \ n \ n解决了我的问题
#5
3
You have to change from wb to w:
你必须从wb改为w:
def __init__(self): self.myCsv = csv.writer(open('Item.csv', 'wb')) self.myCsv.writerow(['title', 'link'])
to
至
def __init__(self): self.myCsv = csv.writer(open('Item.csv', 'w')) self.myCsv.writerow(['title', 'link'])
After changing this, the error disappears, but you can't write to the file (in my case). So after all, I don't have an answer?
更改后,错误消失,但您无法写入文件(在我的情况下)。毕竟,我没有答案?
Source: How to remove ^M
来源:如何删除^ M.
Changing to 'rb' brings me the other error: io.UnsupportedOperation: write
更改为'rb'会给我带来另一个错误:io.UnsupportedOperation:write
#6
0
why not try opening your file as text?
为什么不尝试将文件作为文本打开?
with open(fname, 'rt') as f: lines = [x.strip() for x in f.readlines()]
Additionally here is a link for python 3.x on the official page: https://docs.python.org/3/library/io.htmlAnd this is the open function: https://docs.python.org/3/library/functions.html#open
另外这里是官方页面上python 3.x的链接:https://docs.python.org/3/library/io.html这是开放功能:https://docs.python.org/3/库/ functions.html#开放
If you are really trying to handle it as a binary then consider encoding your string.
如果您真的想要将其作为二进制文件处理,那么请考虑编码您的字符串。
#7
0
You opened the file in binary mode:
您以二进制模式打开文件:
The following code will throw a TypeError: a bytes-like object is required, not 'str'.
以下代码将抛出TypeError:需要类似字节的对象,而不是'str'。
for line in lines: print(type(line))# <class 'bytes'> if 'substring' in line: print('success')
The following code will work - you have to use the decode() function:
以下代码将起作用 - 您必须使用decode()函数:
for line in lines: line = line.decode() print(type(line))# <class 'str'> if 'substring' in line: print('success')
#1
268
You opened the file in binary mode:
您以二进制模式打开文件:
with open(fname, 'rb') as f:
This means that all data read from the file is returned as bytes
objects, not str
. You cannot then use a string in a containment test:
这意味着从文件读取的所有数据都作为字节对象返回,而不是str。然后,您无法在包含测试中使用字符串:
if 'some-pattern' in tmp: continue
You'd have to use a bytes
object to test against tmp
instead:
您必须使用bytes对象来测试tmp:
if b'some-pattern' in tmp: continue
or open the file as a textfile instead by replacing the 'rb'
mode with 'r'
.
或者将文件作为文本文件打开,而不是将'rb'模式替换为'r'。
#2
59
You can encode your string by using .encode()
您可以使用.encode()对字符串进行编码
Example:
例:
'Hello World'.encode()
#3
20
Like it has been already mentioned, you are reading the file in binary mode and then creating a list of bytes. In your following for loop you are comparing string to bytes and that is where the code is failing.
就像已经提到过的那样,您正在以二进制模式读取文件,然后创建一个字节列表。在您的以下for循环中,您将比较字符串与字节,这是代码失败的地方。
Decoding the bytes while adding to the list should work. The changed code should look as follows:
添加到列表时解码字节应该有效。更改的代码应如下所示:
with open(fname, 'rb') as f: lines = [x.decode('utf8').strip() for x in f.readlines()]
The bytes type was introduced in Python 3 and that is why your code worked in Python 2. In Python 2 there was no data type for bytes:
字节类型是在Python 3中引入的,这就是为什么你的代码在Python 2中工作的原因。在Python 2中,没有字节的数据类型:
>>> s=bytes('hello')>>> type(s)<type 'str'>
#4
9
for this small example: import socket
对于这个小例子:import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)mysock.connect(('www.py4inf.com', 80))mysock.send(**b**'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')while True: data = mysock.recv(512) if ( len(data) < 1 ) : break print (data);mysock.close()
adding the "b" before 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n'solved my problem
在'GET http://www.py4inf.com/code/romeo.txt之前添加“b”HTTP / 1.0 \ n \ n解决了我的问题
#5
3
You have to change from wb to w:
你必须从wb改为w:
def __init__(self): self.myCsv = csv.writer(open('Item.csv', 'wb')) self.myCsv.writerow(['title', 'link'])
to
至
def __init__(self): self.myCsv = csv.writer(open('Item.csv', 'w')) self.myCsv.writerow(['title', 'link'])
After changing this, the error disappears, but you can't write to the file (in my case). So after all, I don't have an answer?
更改后,错误消失,但您无法写入文件(在我的情况下)。毕竟,我没有答案?
Source: How to remove ^M
来源:如何删除^ M.
Changing to 'rb' brings me the other error: io.UnsupportedOperation: write
更改为'rb'会给我带来另一个错误:io.UnsupportedOperation:write
#6
0
why not try opening your file as text?
为什么不尝试将文件作为文本打开?
with open(fname, 'rt') as f: lines = [x.strip() for x in f.readlines()]
Additionally here is a link for python 3.x on the official page: https://docs.python.org/3/library/io.htmlAnd this is the open function: https://docs.python.org/3/library/functions.html#open
另外这里是官方页面上python 3.x的链接:https://docs.python.org/3/library/io.html这是开放功能:https://docs.python.org/3/库/ functions.html#开放
If you are really trying to handle it as a binary then consider encoding your string.
如果您真的想要将其作为二进制文件处理,那么请考虑编码您的字符串。
#7
0
You opened the file in binary mode:
您以二进制模式打开文件:
The following code will throw a TypeError: a bytes-like object is required, not 'str'.
以下代码将抛出TypeError:需要类似字节的对象,而不是'str'。
for line in lines: print(type(line))# <class 'bytes'> if 'substring' in line: print('success')
The following code will work - you have to use the decode() function:
以下代码将起作用 - 您必须使用decode()函数:
for line in lines: line = line.decode() print(type(line))# <class 'str'> if 'substring' in line: print('success')