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

本文翻译自:TypeError: a bytes-like object is required, not 'str' when writing to a file in Python3

I've very recently migrated to Py 3.5. 我最近已经迁移到Py 3.5。 This code was working properly in Python 2.7: 这段代码在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问题,但是这个小小的声明困扰着我。


#1楼

参考:https://stackoom.com/question/2EgzX/TypeError-需要类似字节的对象-而在Python-中写入文件时不是-str


#2楼

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 . 这意味着从文件读取的所有数据都以bytes对象而不是str返回。 You cannot then use a string in a containment test: 然后,您不能在收容测试中使用字符串:

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' . 或以文本文件形式打开文件,而不是用'r'代替'rb'模式。


#3楼

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 HTTP / 1.0 \\ n \\ n'之前添加“ b”解决了我的问题


#4楼

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

#5楼

You can encode your string by using .encode() 您可以使用.encode()对字符串进行编码

Example: 例:

'Hello World'.encode()

#6楼

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:写入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值