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

k2arahey  于 2022-12-15  发布在  Python
关注(0)|答案(9)|浏览(160)

我最近迁移到了Python 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

升级到3.5后,我得到了:
TypeError:需要类似字节的对象,而不是“str”
错误出现在最后一行(模式搜索代码)。
我尝试在语句的两侧使用.decode()函数,并且还尝试:

if tmp.find('some-pattern') != -1: continue
  • 都无济于事。
    我能够快速地解决几乎所有的Python 2到Python 3的问题,但是这条小语句一直困扰着我。
bejyjqdl

bejyjqdl1#

对于这个小示例,在'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n'之前添加唯一的b解决了我的问题:

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

字符串
What does the 'b' character do in front of a string literal?

zc0qhyus

zc0qhyus2#

您以二进制模式打开了该文件:
下面的代码将引发TypeError:需要类似字节的对象,而不是“str”。

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

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

for line in lines:
    line = line.decode()
    print(type(line))# <class 'str'>
    if 'substring' in line:
       print('success')
qij5mzcb

qij5mzcb3#

尝试以文本格式打开文件:

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

另外,这里是Python 3.x官方页面的链接:***
这是一个开放函数:* 开放 *
如果你真的想把它作为二进制来处理,那么就考虑对你的字符串进行编码。

3hvapo4f

3hvapo4f4#

当我试图将一个字符(或字符串)转换为bytes时,我遇到了这个错误。在Python 2.7中,代码如下所示:

# -*- coding: utf-8 -*-
print(bytes('ò'))

这是Python 2.7处理Unicode字符的方式。
这在Python 3.6中不起作用,因为bytes需要一个额外的参数来编码,但是这可能有点棘手,因为不同的编码可能输出不同的结果:

print(bytes('ò', 'iso_8859_1')) # prints: b'\xf2'
print(bytes('ò', 'utf-8')) # prints: b'\xc3\xb2'

在我的例子中,为了解决这个问题,我不得不在编码字节时使用iso_8859_1

oyt4ldly

oyt4ldly5#

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

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

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

if 'some-pattern' in tmp: continue

你必须使用一个bytes对象来测试tmp

if b'some-pattern' in tmp: continue

或者通过将'rb'模式替换为'r'来将文件作为文本文件打开。

yhqotfr8

yhqotfr86#

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

'Hello World'.encode()

正如错误描述的那样,为了将字符串写入文件,首先需要将其编码为类似字节的对象,而encode()将其编码为字节字符串。

chhqkbe1

chhqkbe17#

就像前面提到的,你是在二进制模式下阅读文件,然后创建一个字节列表,在下面的for循环中,你是在比较字符串和字节,这就是代码失败的地方。
在添加到列表时解码字节应该可以工作。更改后的代码应该如下所示:

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

bytes类型是在Python 3中引入的,这就是为什么你的代码可以在Python 2中工作。在Python 2中,没有bytes的数据类型:

>>> s=bytes('hello')
>>> type(s)
<type 'str'>
tzdcorbm

tzdcorbm8#

你必须把wb改成w:

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

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

修改后,错误消失了,但你不能写文件(在我的情况下)。所以,毕竟,我没有一个答案?
来源:如何删除^M
更改为'rb'会带来另一个错误:io.UnsupportedOperation:写

lnlaulya

lnlaulya9#

将encode()函数与用单引号括起来的硬编码字符串值沿着使用。
示例:

file.write(answers[i] + '\n'.encode())
  • 或者 *
line.split(' +++$+++ '.encode())

相关问题