Migliore risposta
Spiacenti, non esiste una semplice risposta di una riga a questo problema.
Immagina che una stringa entri in un programma python tramite unoperazione di I / O (letta dal terminale, o dal file, o dalla rete), si fa strada nel programma e viene copiata da un posto allaltro, e infine ottiene loutput tramite unoperazione di I / O. In qualsiasi fase del percorso, se assegni un unicode a un str, vedrai il temuto errore ascii codec can"t encode...
. Sfortunatamente, non esiste un modo semplice per risolverlo se non quello di andare attraverso il codice che fissa tutti i punti.
Ad esempio, considera:
f\_in = open("filein.txt")
line = f\_in.read()
out\_msg = "The input line was: {line}".format(line=line)
f\_out = open("fileout.txt")
A meno che tu non sappia quale codifica è stata utilizzata durante larchiviazione di filein.txt, sei pronto per un comportamento bizzarro e alcuni caratteri nel tuo line
sembreranno spazzatura. (Nota: hai vinto ” t ottenere lerrore ascii codec can"t encode...
, ma i risultati saranno comunque pessimi.) Quindi devi usare qualcosa come: f\_in = codecs.open("filein.txt", "rb", "utf-8")
e poi sperare disperatamente che chiunque abbia memorizzato filein.txt lo aveva memorizzato in utf-8 e non in una delle altre codifiche UTF. (Nota: utf-8 è compatibile con le versioni successive ascii, quindi un file che è stato memorizzato utilizzando ascii regolare si aprirà correttamente utilizzando la codifica utf-8).
A questo punto, ovviamente lo avrai capito a meno che tu non se apri fileout.txt utilizzando una codifica Unicode appropriata, avrai di nuovo dei problemi e riceverai lerrore ascii codec can"t encode...
(se out\_msg contiene caratteri Unicode). Quindi devi fare codecs.open("fileout.txt", "wb", "utf-8")
. (Nota ancora: lutilizzo di una codifica utf-8 per memorizzare ASCII regolari non è un problema, poiché è compatibile con le versioni successive, quindi se il tuo testo non contiene caratteri Unicode non ASCII , il file codificato utf-8 è identico a un normale file ascii.)
La cosa che mi ha fatto inciampare è stata che fare queste due cose non è abbastanza buono. Considera questo codice aggiornato:
f\_in = codecs.open("filein.txt", "rb", "utf-8")
line = f\_in.read()
out\_msg = "The input line was: {line}".format(line=line)
f\_out = codecs.open("fileout.txt", "wb", "utf-8")
Questo potrebbe ancora darti lo stesso temuto errore al terzo linea. Esatto, il problema è che "The input line was: {line}".format(xxx)"
è un str
e se line
contiene qualsiasi carattere Unicode (con cui intendo caratteri che non possono essere codificati in ASCII) sei nei guai.
La soluzione è:
out\_msg = u"The input line was: {line}".format(line=line)
(Sì, questa riga è diversa dalla riga 3 nellesempio di codice. Devi solo guardare attentamente.)
Quindi il gioco è fatto. Devi passare attraverso ogni riga del tuo codice e trova i luoghi in cui unicode viene assegnato a str (o viene inviato a un metodo che prevede un str) e fissa la destinazione in modo che sia unicode anziché str.
Per capire unicode in python meglio, dai unocchiata a: http://farmdev.com/thoughts/23/what-i-thought-i-knew-about-unicode-in-python-amounted-to-nothing/
Per capire Unicode in generale (e io altamente ti consiglio di farlo) leggi “s” di Joel Spolsky Il minimo assoluto che ogni sviluppatore di software deve assolutamente conoscere su Unicode e set di caratteri (No Scuse!) “: http://www.joelonsoftware.com/articles/Unicode.html
E visto che ci sei, potresti anche leggere: Qual è la migliore fonte per conoscere le best practice di Unicode in python?
Quick “n Dirty Hack: Se vuoi solo stampare un po di output in circa ascii puoi fare:
import unicodedata
line = unicodedata.normalize("NFKD", line).encode("ascii","ignore")
Questo sostituirà tutti i caratteri non ASCII con lequivalente ASCII più vicino, o semplicemente ignorerà il carattere se nulla è appropriato . È abbastanza buono per molti scopi …
Risposta
Dovresti convertire le tue stringhe Unicode (che sono fatte di caratteri, ununità disaccoppiata dalla dimensione della memoria) in byte usando la codifica corretta prima di eseguire qualsiasi I / O con esso.
Per impostazione predefinita, Python cerca di codificare la stringa Unicode utilizzando la codifica ASCII durante la scrittura su stdout (ovvero, utilizzando print ), ma questa codifica non può rappresentare tutti i caratteri Unicode, motivo per cui ricevi lerrore: “il codec” ascii “non può” codificare il carattere “. Abbastanza esplicito.
Dovresti scegliere una codifica corretta e codificare la tua stringa Unicode usando quella. Ad esempio, UTF-8 è una codifica efficiente in grado di gestire ogni carattere Unicode. Supponendo che foo sia una stringa Unicode, potresti (e dovresti) fare: print foo.encode (“utf -8 “) invece di print foo . Assicurati solo che il tuo terminale o qualunque cosa capisca la codifica che scegli.Di nuovo: UTF-8 è la codifica più calda in circolazione per scenari come questo, probabilmente vorrai usarlo a meno che tu non abbia esigenze molto specifiche.