Cum să ocolească eroarea Python ' UnicodeEncodeError: ' ascii ' codecul nu poate codifica caracterul … ' când utilizați un script Python pe linia de comandă

Cel mai bun răspuns

Ne pare rău, nu există un răspuns simplu pe o singură linie la această problemă.

Imaginați-vă că un șir intră într-un program python printr-o operație I / O (citită de la terminal, sau din fișier sau din rețea), își face drumul în jurul programului, fiind copiată dintr-un loc în altul, și, în cele din urmă, obține ieșire printr-o operație de I / O. La orice pas, dacă atribuiți un unicode unui str, veți vedea eroarea temută ascii codec can"t encode.... Din păcate, nu există o modalitate ușoară de a remedia problema decât de a merge prin codul dvs. de remediere a tuturor punctelor.

De exemplu, luați în considerare:

f\_in = open("filein.txt")

line = f\_in.read()

out\_msg = "The input line was: {line}".format(line=line)

f\_out = open("fileout.txt")

Cu excepția cazului în care știți ce codificare a fost utilizată la stocarea filein.txt, vă confruntați cu un comportament bizar și unele caractere din line vor arăta ca un gunoi. Nu primiți eroarea ascii codec can"t encode..., dar rezultatele vor fi totuși negative.) Deci, trebuie să utilizați ceva de genul: f\_in = codecs.open("filein.txt", "rb", "utf-8") și apoi să sperați cu disperare că oricine a stocat filein.txt l-a stocat în utf-8 și nu una din celelalte codificări UTF. (Notă: utf-8 este compatibil în sus cu ascii, deci un fișier care a fost stocat folosind ascii obișnuit se va deschide bine folosind codificarea utf-8).

Până acum, evident, veți realiza că dacă nu deschideți fileout.txt folosind o codificare unicode adecvată, veți avea din nou probleme și veți primi eroarea ascii codec can"t encode... (dacă out\_msg conține un caracter unicode). Deci, trebuie să faceți codecs.open("fileout.txt", "wb", "utf-8"). (Notă din nou: utilizarea unei codificări utf-8 pentru a stoca ascii regulate nu este o problemă, deoarece este compatibilă în sus, deci dacă textul dvs. nu conține caractere unicode non ascii , fișierul codat utf-8 este identic cu un fișier ascii obișnuit.)

Lucrul care m-a împiedicat a fost că a face aceste două lucruri nu este suficient de bun. Luați în considerare acest cod actualizat:

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

Acest lucru vă poate oferi în continuare aceeași eroare temută pe a treia linia. Așa este, problema este că "The input line was: {line}".format(xxx)" este un str și dacă line conține orice caractere Unicode (prin care mă refer la caractere care nu pot fi codate în ascii) aveți probleme.

Remedierea pentru aceasta este:

out\_msg = u"The input line was: {line}".format(line=line)

(Da, această linie este diferită de linia 3 din eșantionul de cod. Trebuie doar să te uiți cu atenție.)

Deci, acolo o ai. Trebuie să treci prin fiecare linie a codului dvs. și găsiți locuri în care unicode este atribuit str (sau este trimis la o metodă care așteaptă un str) și fixați destinația pentru a fi unicode în loc de str.

Pentru a înțelege unicode în python mai bine, aruncă o privire la: http://farmdev.com/thoughts/23/what-i-thought-i-knew-about-unicode-in-python-amounted-to-nothing/

Pentru a înțelege unicode în general (și aș extrem de vă recomandăm să faceți acest lucru) citiți Joel Spolsky „s” Minimul absolut pe care fiecare dezvoltator de software trebuie să îl cunoască în mod absolut, pozitiv despre seturile de caractere Unicode și (Nu Scuze!) „: http://www.joelonsoftware.com/articles/Unicode.html

Și, în timp ce vă referiți la asta, ați putea citi și: Care este cea mai bună sursă pentru a afla despre cele mai bune practici Unicode în python?

Quick „n Dirty Hack: Dacă doriți doar să obțineți o ieșire tipărită în ascii aproximative, puteți face:

import unicodedata

line = unicodedata.normalize("NFKD", line).encode("ascii","ignore")

Aceasta va înlocui toate caracterele care nu sunt ascii cu cel mai apropiat echivalent ascii sau doar ignoră caracterul dacă nimic nu este adecvat . Este suficient de bun pentru multe scopuri …

Răspuns

Ar trebui să vă convertiți șirurile Unicode (care sunt formate din caractere, o unitate decuplată de dimensiunea memoriei) în octeți folosind codificarea adecvată înainte de a face orice I / O cu el.

În mod implicit, Python încearcă să codeze șirul Unicode folosind codificarea ASCII atunci când scrie pe stdout (adică, folosind print ), dar această codificare nu poate „reprezenta fiecare caracter Unicode, motiv pentru care primiți această eroare: codecul„ ascii ”nu poate„ codifica caracterul ”. Destul de explicit.

Ar trebui să alegeți o codificare adecvată și să vă codificați șirul Unicode folosind aceasta. De exemplu, UTF-8 este o codificare eficientă care poate gestiona fiecare caracter Unicode. Presupunând că foo este un șir Unicode, puteți (și ar trebui) să faceți: print foo.encode („utf -8 „) în loc de doar print foo . Asigurați-vă că terminalul dvs. sau orice altceva înțelege codarea pe care o alegeți.Din nou: UTF-8 este cea mai tare codificare existentă pentru astfel de scenarii, probabil că veți dori să o utilizați dacă nu aveți nevoi specifice.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *