TypeError: een bytes-achtig object is vereist, niet ‘str’ bij het schrijven naar een bestand in Python3

Ik ben zeer recent gemigreerd naar Py 3.5.
Deze code werkte correct in 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

Na het upgraden naar 3.5 krijg ik het volgende:

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

fout op de laatste regel (de patroonzoekcode).

Ik heb geprobeerd de functie .decode() aan weerszijden van de instructie te gebruiken, ook geprobeerd:

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

– tevergeefs.

Ik heb bijna alle 2:3-problemen snel kunnen oplossen, maar dit kleine statement irriteert me.


Antwoord 1, autoriteit 100%

Je hebt het bestand in binaire modus geopend:

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

Dit betekent dat alle gegevens die uit het bestand worden gelezen, worden geretourneerd als bytes-objecten, niet als str. U kunt dan geen string gebruiken in een insluitingstest:

if 'some-pattern' in tmp: continue

Je zou in plaats daarvan een bytes object moeten gebruiken om te testen tegen tmp:

if b'some-pattern' in tmp: continue

of open het bestand in plaats daarvan als een tekstbestand door de modus 'rb' te vervangen door 'r'.


Antwoord 2, autoriteit 41%

Je kunt je string coderen met .encode()

Voorbeeld:

'Hello World'.encode()

Antwoord 3, autoriteit 9%

Zoals het al is genoemd, leest u het bestand in binaire modus en maakt u vervolgens een lijst met bytes. In je volgende for-lus vergelijk je string met bytes en dat is waar de code faalt.

Het decoderen van de bytes tijdens het toevoegen aan de lijst zou moeten werken. De gewijzigde code moet er als volgt uitzien:

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

Het type bytes is geïntroduceerd in Python 3 en daarom werkte je code in Python 2. In Python 2 was er geen gegevenstype voor bytes:

>>> s=bytes('hello')
>>> type(s)
<type 'str'>

Antwoord 4, autoriteit 4%

Je moet veranderen van wb naar w:

def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'wb')) 
    self.myCsv.writerow(['title', 'link'])

naar

def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'w'))
    self.myCsv.writerow(['title', 'link'])

Nadat je dit hebt gewijzigd, verdwijnt de fout, maar je kunt niet naar het bestand schrijven (in mijn geval). Dus ik heb tenslotte geen antwoord?

Bron: Hoe ^M te verwijderen

Veranderen naar ‘rb’ brengt me de andere fout: io.UnsupportedOperation: write


Antwoord 5, autoriteit 2%

voor dit kleine voorbeeld:

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

het toevoegen van de "b" voordat
‘KRIJG http://www.py4inf.com/code/romeo.txt HTTP /1.0\n\n’
mijn probleem opgelost


Antwoord 6, autoriteit 2%

Gebruik de functie encode() samen met de hardgecodeerde tekenreekswaarde tussen een enkel aanhalingsteken.

Bijvoorbeeld:

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

OF

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

Antwoord 7, autoriteit 2%

Je hebt het bestand in binaire modus geopend:

De volgende code wordt gegooid
a TypeError: een bytes-achtig object is vereist, niet ‘str’.

for line in lines:
    print(type(line))# <class 'bytes'>
    if 'substring' in line:
       print('success')

De volgende code zal werken – u moet de functie decode() gebruiken:

for line in lines:
    line = line.decode()
    print(type(line))# <class 'str'>
    if 'substring' in line:
       print('success')

Antwoord 8

waarom probeert u uw bestand niet als tekst te openen?

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

Daarnaast is hier een link voor python 3.x op de officiële pagina:
https://docs.python.org/3/library/io.html
En dit is de open functie: https://docs.python.org/3/ library/functions.html#open

Als je het echt als een binair bestand probeert te verwerken, overweeg dan om je string te coderen.


Antwoord 9

Ik kreeg deze foutmelding toen ik probeerde een char (of string) naar bytes te converteren, de code zag er ongeveer zo uit met Python 2.7:

# -*- coding: utf-8 -*-
print( bytes('o') )

Dit is de manier van Python 2.7 bij het omgaan met unicode-tekens.

Dit werkt niet met Python 3.6, aangezien bytes een extra argument voor codering nodig hebben, maar dit kan een beetje lastig zijn, aangezien verschillende codering een ander resultaat kan opleveren:

print( bytes('o', 'iso_8859_1') ) # prints: b'\xf2'
print( bytes('o', 'utf-8') ) # prints: b'\xc3\xb2'

In mijn geval moest ik iso_8859_1 gebruiken bij het coderen van bytes om het probleem op te lossen.

Ik hoop dat dit iemand helpt.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes