关于python:TypeError:在Python3中写入文件时需要类似字节的对象,而不是’str’

TypeError: a bytes-like object is required, not 'str' when writing to a file in Python3

我最近刚搬到PY 3.5。此代码在python 2.7中正常工作:

1
2
3
4
5
6
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

升级到3.5后,我得到:

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

最后一行(模式搜索代码)出错。

我试过在语句的两边使用.decode()函数,也试过:

1
if tmp.find('some-pattern') != -1: continue

-无济于事。

我能很快解决几乎所有的2:3问题,但这个小小的声明让我心烦意乱。


您以二进制模式打开了文件:

1
with open(fname, 'rb') as f:

这意味着从文件中读取的所有数据都作为bytes对象返回,而不是作为str对象返回。然后不能在包含测试中使用字符串:

1
if 'some-pattern' in tmp: continue

您必须使用bytes对象来测试tmp而不是:

1
if b'some-pattern' in tmp: continue

或者将文件作为文本文件打开,而不是用'r'替换'rb'模式。


可以使用.encode()对字符串进行编码。

例子:

1
'Hello World'.encode()


正如已经提到的,您正在以二进制模式读取文件,然后创建字节列表。在下面的for循环中,您将字符串与字节进行比较,这就是代码失败的地方。

在添加到列表时解码字节应该可以工作。更改后的代码应如下所示:

1
2
with open(fname, 'rb') as f:
    lines = [x.decode('utf8').strip() for x in f.readlines()]

字节类型是在python 3中引入的,这就是代码在python 2中工作的原因。在Python2中,没有字节的数据类型:

1
2
3
>>> s=bytes('hello')
>>> type(s)
<type 'str'>

对于这个小例子:导入插座

1
2
3
4
5
6
7
8
9
10
11
12
13
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

'
)

while True:
    data = mysock.recv(512)
    if ( len(data) < 1 ) :
        break
    print (data);

mysock.close()

在前面加上"B"'获取http://www.py4inf.com/code/romeo.txt http/1.0'解决了我的问题


您必须从WB更改为W:

1
2
3
def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'wb'))
    self.myCsv.writerow(['title', 'link'])

1
2
3
def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'w'))
    self.myCsv.writerow(['title', 'link'])

更改后,错误消失,但您无法写入文件(在我的情况下)。所以,毕竟,我没有答案?

来源:如何删除^M

更改为"rb"会带来另一个错误:io.unsupportedOperation:write


您以二进制模式打开了文件:

以下代码将引发类型错误:需要类似对象的字节,而不是"str"。

1
2
3
4
for line in lines:
    print(type(line))# <class 'bytes'>
    if 'substring' in line:
       print('success')

以下代码可以工作-您必须使用decode()函数:

1
2
3
4
5
for line in lines:
    line = line.decode()
    print(type(line))# <class 'str'>
    if 'substring' in line:
       print('success')


为什么不尝试以文本形式打开文件?

1
2
with open(fname, 'rt') as f:
    lines = [x.strip() for x in f.readlines()]

另外,在官方页面上还有一个关于python 3.x的链接:https://docs.python.org/3/library/io.html网站这是open函数:https://docs.python.org/3/library/functions.html open

如果您真的想把它当作二进制文件来处理,那么考虑对字符串进行编码。


使用encode()函数以及单引号中给定的硬编码字符串值。

前任:

1
2
file.write(answers[i] + '
'
.encode())

1
line.split(' +++$+++ '.encode())