Sono migrato molto recentemente a Py 3.5. Questo codice funzionava correttamente 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
Dopo l'aggiornamento a 3.5, sto ottenendo il:
TypeError: a bytes-like object is required, not 'str'
sull'ultima linea (il codice di ricerca del modello).
Ho provato ad usare la funzione .decode()
su entrambi i lati della dichiarazione, ho anche provato:
if tmp.find('some-pattern') != -1: continue
- senza risultato.
Sono stato in grado di risolvere quasi tutti i problemi 2:3 rapidamente, ma questa piccola affermazione mi sta dando fastidio.
Hai aperto il file in modalità binaria:
with open(fname, 'rb') as f:
Questo significa che tutti i dati letti dal file sono restituiti come oggetti bytes
, non str
. Non puoi quindi usare una stringa in un test di contenimento:
if 'some-pattern' in tmp: continue
Dovresti invece usare un oggetto bytes
per fare il test su tmp
:
if b'some-pattern' in tmp: continue
o aprire il file come file di testo sostituendo il modo 'rb'
con 'r'
.
Come è stato già menzionato, state leggendo il file in modalità binaria e poi creando una lista di byte. Nel tuo seguente ciclo for stai confrontando la stringa con i byte ed è qui che il codice sta fallendo.
Decodificare i byte mentre si aggiunge alla lista dovrebbe funzionare. Il codice modificato dovrebbe apparire come segue:
with open(fname, 'rb') as f:
lines = [x.decode('utf8').strip() for x in f.readlines()]
Il tipo bytes è stato introdotto in Python 3 e questo è il motivo per cui il tuo codice funzionava in Python 2. In Python 2 non c'era un tipo di dati per i byte:
>>> s=bytes('hello')
>>> type(s)
<type 'str'>
per questo piccolo esempio: importare 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()
aggiungendo la "b" prima 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n' risolto il mio problema