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

时间:2022-11-07 18:20:07

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')