TypeError: et byte-lignende objekt er påkrevd, ikke 'str' når du skriver til en fil i Python3

Jeg har nylig migrert til Py 3.5. Denne koden fungerte som den skulle i 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

Etter å ha oppgradert til 3.5, får jeg:

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

feil på den siste linjen (mønstersøkekoden).

Jeg har også prøvd å bruke .decode()-funksjonen på hver side av setningen:

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

- til ingen nytte.

Jeg var i stand til å løse nesten alle 2:3-problemene raskt, men denne lille uttalelsen plager meg.

Løsning

Du åpnet filen i binær modus:

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

Dette betyr at alle data som leses fra filen returneres som bytes-objekter, ikke str. Du kan da ikke bruke en streng i en inneslutningstest:

if 'some-pattern' in tmp: continue

Du må bruke et bytes-objekt for å teste mot tmp i stedet:

if b'some-pattern' in tmp: continue

eller åpne filen som en tekstfil i stedet ved å erstatte 'rb'-modus med 'r'.

Kommentarer (3)

Som det allerede er nevnt, leser du filen i binær modus og oppretter deretter en liste over byte. I følgende for-løkke sammenligner du streng med byte, og det er der koden feiler.

Dekoding av byte mens du legger til listen skal fungere. Den endrede koden skal se ut som følger:

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

Byte-typen ble introdusert i Python 3, og det er derfor koden din fungerte i Python 2. I Python 2 var det ingen datatype for bytes:

>>> s=bytes('hello')
>>> type(s)
Kommentarer (0)

for dette lille eksemplet: importstikkontakt

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()

ved å legge til "b" før 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n' løste problemet mitt

Kommentarer (0)