Legjobb válasz
Sajnáljuk, erre a kérdésre nincs egyszerű egysoros válasz.
Képzelje el, hogy egy karakterlánc egy I / O művelet révén (a terminálról, fájlról vagy a hálózatról olvasható) érkezik a python programba, és így megkerüli a programot, ahonnan helyről helyre másolják, végül kimenetet kap egy I / O művelettel. Bármely lépésben, ha hozzárendel egy unicode-ot egy str-hez, látni fogja a rettegett ascii codec can"t encode...
hibát. Sajnos a kijavításra nincs egyszerű mód, csak a továbbjutás a kódodon keresztül rögzítve az összes helyet.
Például fontolja meg:
f\_in = open("filein.txt")
line = f\_in.read()
out\_msg = "The input line was: {line}".format(line=line)
f\_out = open("fileout.txt")
Hacsak nem tudja, milyen kódolást használtak a filein.txt fájl tárolásakor, furcsa viselkedést tanúsít, és a line
fájl néhány karaktere szemétnek fog tűnni. (Megjegyzés: Ön nyert ” nem kapja meg a ascii codec can"t encode...
hibát, de az eredmények ennek ellenére rosszak lesznek.) Tehát valami olyasmit kell használnia, hogy: f\_in = codecs.open("filein.txt", "rb", "utf-8")
, majd reménykednie kétségbeesetten hogy aki a filein.txt fájlt tárolta, azt az utf-8-ban tárolta, és nem a többi UTF kódolás egyikét. (Megjegyzés: az utf-8 felfelé kompatibilis az ascii fájlokkal, így a normál ascii használatával tárolt fájlok rendben megnyílnak az utf-8 kódolással).
Mostanra nyilvánvalóan rájöttél, hogy hacsak nem Nyissa meg a fileout.txt fájlt megfelelő unicode kódolással, így ismét bajba kerül, és megkapja a ascii codec can"t encode...
hibát (ha az out\_msg tartalmaz unicode karaktert). Tehát meg kell tennie codecs.open("fileout.txt", "wb", "utf-8")
. (Megjegyzés: még egyszer: az utf-8 kódolás használata a szokásos ascii tárolására nem jelent problémát, mivel felfelé kompatibilis, tehát ha a szövege nem tartalmaz nem ascii unicode karaktereket , az utf-8 kódolású fájl megegyezik egy szokásos ascii fájllal.)
A dolog buktatott bennem, hogy e két dolog elvégzése nem elég jó. Vegye figyelembe ezt a frissített kódot:
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")
Ez még mindig ugyanazt a rettegett hibát okozhatja a harmadiknál vonal. Így van, a probléma az, hogy a "The input line was: {line}".format(xxx)"
egy str
és ha line
tartalmaz bármilyen unicode karakter (ez alatt olyan karaktereket értek, amelyek nem kódolhatók ascii-ba) bajban vannak.
Ennek javítása:
out\_msg = u"The input line was: {line}".format(line=line)
(Igen, ez a sor eltér a kódminta 3. sorától. Csak alaposan meg kell néznie.)
Tehát megvan. Végig kell menned kódjának minden sorát, és keresse meg azokat a helyeket, ahol az unicode-ot hozzárendelik az str-hez (vagy olyan módszerhez küldik, amely str-et vár), és javítsa a célt unicode-ként str helyett.
Az unicode megértéséhez jobb a python, vessen egy pillantást a következőre: http://farmdev.com/thoughts/23/what-i-thought-i-knew-about-unicode-in-python-amounted-to-nothing/
Az unicode általános megértéséhez (és nagyon javasoljuk, hogy ezt tegye) olvassa el Joel Spolsky “Abszolút minimumát” Minden szoftverfejlesztőnek feltétlenül, pozitívan tudnia kell az Unicode és a karakterkészletekről (Nem Mentségek!) “: http://www.joelonsoftware.com/articles/Unicode.html
És amíg foglalkozik vele, elolvashatja: Mi a legjobb forrás az unicode bevált módszereinek megismeréséhez a pythonban?
Gyors “n Dirty Hack: Ha csak egy kimenetet szeretne hozzávetőleges ascii formátumban kinyomtatni, megteheti:
import unicodedata
line = unicodedata.normalize("NFKD", line).encode("ascii","ignore")
Ez az összes nem ascii karaktert a legközelebbi ascii megfelelővel helyettesíti, vagy csak figyelmen kívül hagyja a karaktert, ha semmi nem megfelelő . Sok célra elég …
Válasz
Az Unicode karakterláncokat (amelyek karakterekből állnak, a memória méretétől elválasztva) bájtokká alakítják át a megfelelő kódolással mielőtt bármilyen I / O-t csinálna vele.
Alapértelmezés szerint a Python az stdout-ba íráskor megpróbálja az Unicode karakterláncot az ASCII kódolással kódolni (azaz print ), de ez a kódolás nem képes minden Unicode karaktert ábrázolni, ezért kapja ezt a hibát: “” az ascii “kodek nem” kódolhatja a karaktert “. Elég egyértelmű.
Válasszon megfelelő kódolást, és ezzel kódolja az Unicode karakterláncot. Például az UTF-8 egy hatékony kódolás, amely képes kezelni minden Unicode karaktert. Ha feltételezzük, hogy a foo egy Unicode karakterlánc, akkor megteheti (és meg kell tennie): foo.encode (“utf -8 “) a foo helyett. Csak győződjön meg róla, hogy a terminál vagy bármi más megérti a választott kódolást.Ismét: Az UTF-8 a legforróbb kódolás odakinn az ilyen forgatókönyvekhez, valószínűleg használni fogja, hacsak nincsenek nagyon speciális igényei.