Подтвердить что ты не робот

TypeError: требуется байтоподобный объект, а не 'str' при записи в файл в Python3

Недавно я перешел на Py 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: a bytes-like object is required, not 'str'

на последней строке (код поиска шаблона).

Я попытался использовать функцию .decode() по обе стороны инструкции, также попытался:

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

- безрезультатно.

Я смог быстро решить почти все проблемы 2: 3, но это небольшое выражение подслушивает меня.

4b9b3361

Ответ 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' на 'r'.

Ответ 2

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

Пример:

'Hello World'.encode()

Ответ 3

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

Декодирование байтов при добавлении в список должно работать. Измененный код должен выглядеть следующим образом:

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

Ответ 4

Вам нужно перейти от 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'])

После изменения этой ошибки ошибка исчезает, но вы не можете записать файл (в моем случае). Так что, в конце концов, у меня нет ответа?

Источник: Как удалить ^ M

Переход на "rb" приносит мне другую ошибку: io.UsupportedOperation: write

Ответ 5

для этого небольшого примера:   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()

добавление "b" до 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n' решил мою проблему

Ответ 6

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

Следующий код выдаст ошибку 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')

Ответ 7

Почему бы не попробовать открыть файл в виде текста?

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

Кроме того, здесь есть ссылка для python 3.x на официальной странице: https://docs.python.org/3/library/io.html И это открытая функция: https://docs.python.org/3/library/functions.html#open

Если вы действительно пытаетесь обработать его как двоичный код, тогда рассмотрите кодировку вашей строки.

Ответ 8

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

Пример:

file.write(answers[i] + '\n'.encode())

ИЛИ ЖЕ

line.split(' +++$+++ '.encode())