TypeError: ein bytes-ähnliches Objekt ist erforderlich, nicht 'str' beim Schreiben in eine Datei in Python3

I've sehr vor kurzem migriert zu Py 3.5. Dieser Code wurde ordnungsgemäß in Python 2.7 arbeiten:

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

Nach dem Upgrade auf 3.5 bekomme ich die:

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

Fehler in der letzten Zeile (dem Code für die Mustersuche).

Ich habe versucht, mit der .decode() Funktion auf jeder Seite der Anweisung, auch versucht:

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

Ich konnte fast alle 2:3-Probleme schnell beheben, aber diese kleine Aussage stört mich.

Lösung

Sie haben die Datei im Binärmodus geöffnet:

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

Das bedeutet, dass alle aus der Datei gelesenen Daten als bytes-Objekte zurückgegeben werden, nicht als str. Sie können dann keinen String in einem Containment-Test verwenden:

if 'some-pattern' in tmp: continue

Sie müssen stattdessen ein "Bytes"-Objekt verwenden, um gegen "tmp" zu testen:

if b'some-pattern' in tmp: continue

oder öffnen Sie die Datei stattdessen als Textdatei, indem Sie den Modus "rb" durch "r" ersetzen.

Kommentare (3)

Wie bereits erwähnt, lesen Sie die Datei im Binärmodus und erstellen dann eine Liste von Bytes. In der folgenden for-Schleife vergleichen Sie die Zeichenkette mit den Bytes, und genau hier schlägt der Code fehl.

Die Dekodierung der Bytes beim Hinzufügen zur Liste sollte funktionieren. Der geänderte Code sollte wie folgt aussehen:

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

Der Byte-Typ wurde in Python 3 eingeführt und deshalb funktionierte Ihr Code in Python 2. In Python 2 gab es keinen Datentyp für Bytes:

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

für dieses kleine Beispiel: Socket importieren

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

Hinzufügen des "b" vor 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n' hat mein Problem gelöst

Kommentare (0)