TypeError: изисква се обект, подобен на bytes, а не '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 бързо, но това малко твърдение ме притеснява.

Решение

Отворили сте файла в двоичен режим:

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

Коментари (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)
Коментари (0)

за този малък пример: импортиране на сокет

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' реши проблема ми

Коментари (0)