Bedste svar
Beklager, der er ikke noget simpelt svar på en linje på dette problem.
Forestil dig, at en streng kommer ind i et python-program via en I / O-operation (læst fra terminal eller fra fil eller fra netværket), den finder vej rundt i programmet og bliver kopieret fra sted til sted, og endelig får den output via en I / O-operation. På ethvert trin på vejen, hvis du tildeler en unicode til en str, vil du se den frygtede ascii codec can"t encode...
-fejl. Desværre er der ingen nem måde at rette det på andet end at gå gennem din kode, der løser alle pletterne.
Overvej f.eks .:
f\_in = open("filein.txt")
line = f\_in.read()
out\_msg = "The input line was: {line}".format(line=line)
f\_out = open("fileout.txt")
Medmindre du ved, hvilken kodning der blev brugt ved lagring af filein.txt, er du i for en vis bizar opførsel, og nogle tegn i din line
vil se ud som affald. t få ascii codec can"t encode...
-fejlen, men resultaterne bliver alligevel dårlige.) Så du skal bruge noget som: f\_in = codecs.open("filein.txt", "rb", "utf-8")
og så håbe desperat at den, der lagrede filein.txt, havde gemt den i utf-8 og ikke en af de andre UTF-kodninger. (Bemærk: utf-8 er opad kompatibel med ascii, så en fil, der blev gemt ved hjælp af almindelig ascii, åbner fint ved hjælp af utf-8-kodning).
Nu er du selvfølgelig klar over, at medmindre du åben fileout.txt ved hjælp af en passende unicode-kodning, vil du igen løbe ind i problemer og få ascii codec can"t encode...
fejlen (hvis din out\_msg indeholder noget unicode-tegn). Så du skal gøre codecs.open("fileout.txt", "wb", "utf-8")
. (Bemærk igen: at bruge en utf-8-kodning til at gemme almindelig ascii er ikke et problem, da det er opadgående kompatibelt, så hvis din tekst ikke indeholder unicode-tegn, der ikke er ascii , den utf-8-kodede fil er identisk med en almindelig ascii-fil.)
Det, der fik mig ud, var, at det ikke er godt nok at gøre disse to ting. Overvej denne opdaterede kode:
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")
Dette kan stadig give dig den samme frygtede fejl på den tredje linje. Det er rigtigt, problemet er, at "The input line was: {line}".format(xxx)"
er en str
, og hvis line
indeholder alle unicode-tegn (som jeg mener tegn, der ikke kan kodes til ascii), du er i problemer.
Fixen til det er:
out\_msg = u"The input line was: {line}".format(line=line)
(Ja, denne linje er forskellig fra linje 3 i kodeeksemplet. Du skal bare se nøje.)
Så der har du det. Nødt til at gå igennem hver linje i din kode og find steder, hvor unicode tildeles str (eller sendes til en metode, der forventer en str), og fastlæg, at destinationen skal være unicode i stedet for str.
At forstå unicode i bedre python, se på: http://farmdev.com/thoughts/23/what-i-thought-i-knew-about-unicode-in-python-amounted-to-nothing/
For at forstå unicode generelt (og jeg ville meget anbefaler at du gør dette) læs Joel Spolsky “s” Det absolutte minimum Hver softwareudvikler Absolut, positivt skal vide om Unicode og tegnsæt (Nej Undskyldninger!) “: http://www.joelonsoftware.com/articles/Unicode.html
Og mens du handler om det, kan du lige så godt læse: Hvad er den bedste kilde til at lære om unicode-bedste praksis i python?
Hurtig “n Beskidt hack: Hvis du bare vil få noget output trykt i omtrentlige ascii, kan du gøre:
import unicodedata
line = unicodedata.normalize("NFKD", line).encode("ascii","ignore")
Dette erstatter alle ikke-ascii-tegn med det nærmeste ascii-ækvivalent eller ignorerer bare tegnet, hvis intet er passende . Er god nok til mange formål …
Svar
Du skal konvertere dine Unicode-strenge (som er lavet af tegn, en enhed afkoblet fra hukommelsesstørrelse) til byte ved hjælp af den korrekte kodning inden du foretager nogen I / O med det.
Som standard forsøger Python at kode din Unicode-streng ved hjælp af ASCII-kodningen, når du skriver til stdout (dvs. ved hjælp af udskriv ), men denne kodning kan ikke repræsentere alle Unicode-tegn, hvorfor du får den fejl: “” ascii “codec kan ikke kode kode”. Temmelig eksplicit.
Du skal vælge en korrekt kodning og kode din Unicode-streng ved hjælp af den. For eksempel er UTF-8 en effektiv kodning, der kan håndtere alle Unicode-tegn. Antages det, at foo er en Unicode-streng, kan du (og bør) gøre: udskrive foo.encode (“utf -8 “) i stedet for bare print foo . Bare sørg for, at din terminal eller hvad der forstår den kodning, du vælger.Igen: UTF-8 er den hotteste kodning derude til scenarier som denne, du vil sandsynligvis bruge den, medmindre du har meget specifikke behov.