Вопрос-Ответ

"TypeError: a bytes-like object is required, not 'str'" when handling file content in Python 3

"TypeError: требуется объект, подобный байтам, а не 'str'" при обработке содержимого файла в Python 3

Я совсем недавно перешел на 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, в if 'some-pattern' in tmp: continue строке, я получаю сообщение об ошибке, которое гласит:

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

Я не смог устранить проблему, используя .decode() с обеих сторон in, и я не мог исправить это с помощью

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

Что не так и как мне это исправить?

Переведено автоматически
Ответ 1

Вы открыли файл в двоичном режиме:

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

Это означает, что все данные, считанные из файла, возвращаются как bytes объекты, а не str. В этом случае вы не сможете использовать строку в тесте сдерживания:

if 'some-pattern' in tmp: continue

Вместо этого вам придется использовать bytes объект для проверки tmp:

if b'some-pattern' in tmp: continue

или вместо этого откройте файл как текстовый файл, заменив 'rb' mode на 'r'.

Ответ 2

Вы можете закодировать свою строку с помощью .encode()

Пример:

'Hello World'.encode()

Как описано в ошибке, чтобы записать строку в файл, вам нужно сначала закодировать ее в байтоподобный объект, и encode() кодирует ее в байтоподобную строку.

Ответ 3

Как уже упоминалось, вы считываете файл в двоичном режиме, а затем создаете список байтов. В следующем цикле 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'>
Ответ 4

Вы должны перейти с 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: write

python python-3.x string file