Hogyan lehet megkerülni a Python hibát ' UnicodeEncodeError: ' ascii ' kodek nem kódolhatja a karaktert … ' ha Python szkriptet használ a parancssorban


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.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük