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, λαμβάνω το εξής: "Η Python 3.5 δεν είναι έτοιμη για την αναβάθμιση της Python 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)

Όπως έχει ήδη αναφερθεί, διαβάζετε το αρχείο σε δυαδική μορφή και στη συνέχεια δημιουργείτε μια λίστα bytes. Στο βρόχο for που ακολουθεί συγκρίνετε τη συμβολοσειρά με τα bytes και εκεί αποτυγχάνει ο κώδικας.

Η αποκωδικοποίηση των bytes κατά την προσθήκη στη λίστα θα πρέπει να λειτουργεί. Ο τροποποιημένος κώδικας θα πρέπει να έχει την ακόλουθη μορφή:

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

Ο τύπος bytes εισήχθη στην Python 3 και γι' αυτό ο κώδικάς σας λειτουργούσε στην Python 2. Στην Python 2 δεν υπήρχε τύπος δεδομένων για bytes:

>>> s=bytes('hello')
>>> type(s)
Σχόλια (0)

για αυτό το μικρό παράδειγμα: εισαγωγή 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&#39, έλυσε το πρόβλημά μου

Σχόλια (0)