我最近迁移到了Python3.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中,在tmp:contain行中的if“some pattern”上,我得到一个错误,该错误表示:
TypeError: a bytes-like object is required, not 'str'
我无法在in的任一侧使用.dedecode()解决问题,也无法使用
if tmp.find('some-pattern') != -1: continue
有什么问题,我该如何解决?
正如前面已经提到的,您正在以二进制模式读取文件,然后创建一个字节列表。在下面的for循环中,您将字符串与字节进行比较,这就是代码失败的地方。
在添加到列表中时解码字节应该可以工作。更改后的代码应如下所示:
with open(fname, 'rb') as f:
lines = [x.decode('utf8').strip() for x in f.readlines()]
字节类型是在Python 3中引入的,这就是为什么您的代码在Python 2中工作。在Python 2中,字节没有数据类型:
>>> s=bytes('hello')
>>> type(s)
<type 'str'>
当我试图将一个字符(或字符串)转换为字节时,出现了这个错误,Python 2.7的代码如下:
# -*- coding: utf-8 -*-
print(bytes('ò'))
这是Python 2.7处理Unicode字符时的方式。
这在Python 3.6中不起作用,因为字节需要额外的参数进行编码,但这可能有点棘手,因为不同的编码可能会输出不同的结果:
print(bytes('ò', 'iso_8859_1')) # prints: b'\xf2'
print(bytes('ò', 'utf-8')) # prints: b'\xc3\xb2'
在我的例子中,为了解决这个问题,我必须在编码字节时使用iso_8859_1。
您以二进制模式打开了文件:
with open(fname, 'rb') as f:
这意味着从文件中读取的所有数据都将作为字节对象返回,而不是str。然后不能在包含测试中使用字符串:
if 'some-pattern' in tmp: continue
您必须使用一个字节对象来测试tmp:
if b'some-pattern' in tmp: continue
或将“rb”模式替换为“r”,将文件作为文本文件打开。