Έχω μεταναστεύσει πολύ πρόσφατα στην 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'
.
Όπως έχει ήδη αναφερθεί, διαβάζετε το αρχείο σε δυαδική μορφή και στη συνέχεια δημιουργείτε μια λίστα 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)
<type 'str'>
για αυτό το μικρό παράδειγμα: εισαγωγή 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', έλυσε το πρόβλημά μου