"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:
withopen(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
Вы открыли файл в двоичном режиме:
withopen(fname, 'rb') as f:
Это означает, что все данные, считанные из файла, возвращаются как bytes объекты, а не str. В этом случае вы не сможете использовать строку в тесте сдерживания:
if'some-pattern'in tmp: continue
Вместо этого вам придется использовать bytes объект для проверки tmp:
ifb'some-pattern'in tmp: continue
или вместо этого откройте файл как текстовый файл, заменив 'rb' mode на 'r'.
Ответ 2
Вы можете закодировать свою строку с помощью .encode()
Пример:
'Hello World'.encode()
Как описано в ошибке, чтобы записать строку в файл, вам нужно сначала закодировать ее в байтоподобный объект, и encode() кодирует ее в байтоподобную строку.
Ответ 3
Как уже упоминалось, вы считываете файл в двоичном режиме, а затем создаете список байтов. В следующем цикле for вы сравниваете строку с байтами, и именно здесь происходит сбой кода.
Декодирование байтов при добавлении в список должно сработать. Измененный код должен выглядеть следующим образом:
withopen(fname, 'rb') as f: lines = [x.decode('utf8').strip() for x in f.readlines()]
Тип bytes был введен в Python 3, и именно поэтому ваш код работал в Python 2. В Python 2 не было типа данных для bytes: