Kuinka kiertää Python-virhe ' UnicodeEncodeError: ' ascii ' koodekki ei voi koodata merkkiä … ' kun käytät Python-komentosarjaa komentorivillä


Paras vastaus

Valitettavasti tähän ongelmaan ei ole yksinkertaista yksirivistä vastausta.

Kuvittele, että jono tulee python-ohjelmaan I / O-toiminnon kautta (luetaan päätelaitteesta, tiedostosta tai verkosta), se kiertää ohjelmaa kopioimalla paikasta toiseen, ja lopulta se saa tuotoksen I / O-toiminnon kautta. Jos määrität stricille unicoden missä tahansa vaiheessa, näet pelätyn ascii codec can"t encode... -virheen. Valitettavasti sen korjaamiseen ei ole muuta tapaa kuin mennä korjaamalla kaikki paikat koodisi kautta.

Harkitse esimerkiksi:

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

line = f\_in.read()

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

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

Ellet tiedä, mitä koodausta on käytetty tiedostojen tallentamiseen tiedostoon.txt, sinulla on omituista käyttäytymistä ja jotkut line -kentässä olevat merkit näyttävät roskilta. (Huomaa: voitit ” t saa ascii codec can"t encode... -virheen, mutta tulokset ovat silti huonot.) Joten sinun on käytettävä jotain sellaista: f\_in = codecs.open("filein.txt", "rb", "utf-8") ja toivottava epätoivoisesti että joka tallentanut filein.txt-tiedoston, se oli tallentanut sen utf-8: een eikä muuhun UTF-koodaukseen. (Huomaa: utf-8 on ylöspäin yhteensopiva ascii: n kanssa, joten tavallisella ascii: lla tallennettu tiedosto avautuu hienosti utf-8-koodauksella).

Tähän mennessä olet selvästikin ymmärtänyt, ellet avaamalla fileout.txt käyttämällä asianmukaista unicode-koodausta, olet taas joutumassa vaikeuksiin ja saat ascii codec can"t encode... -virheen (jos out\_msg-tiedosto sisältää unicode-merkkiä). Joten sinun on tehtävä codecs.open("fileout.txt", "wb", "utf-8"). (Huomaa vielä kerran: utf-8-koodauksen käyttö tavallisten ascii-tiedostojen tallentamiseen ei ole ongelma, koska se on ylöspäin yhteensopiva, joten jos teksti ei sisällä muita kuin ascii-unicode-merkkejä , utf-8-koodattu tiedosto on identtinen tavallisen ascii-tiedoston kanssa.)

Minua kompastti se, että näiden kahden asian tekeminen ei ole tarpeeksi hyvää. Harkitse tätä päivitettyä koodia:

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

Tämä voi silti antaa sinulle saman pelätyn virheen kolmannella linja. Se on oikein, ongelmana on, että "The input line was: {line}".format(xxx)" on str ja jos line sisältää kaikki unicode-merkit (joilla tarkoitan merkkejä, joita ei voida koodata ascii-muotoon), olet pulassa.

Korjaus tähän on:

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

(Kyllä, tämä rivi eroaa koodinäytteen rivistä 3. Sinun täytyy vain katsoa huolellisesti.)

Joten sinulla on se. Sinun täytyy käydä läpi koodisi jokaisella rivillä ja etsi paikkoja, joissa unicode on määritetty str: lle (tai lähetetään menetelmälle, joka odottaa str: tä) ja korjaa kohde unicodeksi str: n sijasta.

Unicoden ymmärtäminen python parempi, katsokaa: http://farmdev.com/thoughts/23/what-i-thought-i-knew-about-unicode-in-python-amounted-to-nothing/

Ymmärtääksesi unicodea yleensä (ja haluaisin erittäin suosittele, että teet tämän) lue Joel Spolskyn ehdoton vähimmäismäärä Jokaisen ohjelmistokehittäjän on ehdottomasti, positiivisesti tiedettävä Unicode- ja merkistöjoukot (Ei Anteeksi!) ”: http://www.joelonsoftware.com/articles/Unicode.html

Ja kun olet siitä kiinnostunut, voit yhtä hyvin lukea: Mikä on paras lähde oppia unicoden parhaista käytännöistä pythonissa?

Nopea ”n Dirty Hack: Jos haluat vain tulostaa jonkin verran tulosta likimääräisenä ascii-muodossa, voit tehdä sen:

import unicodedata

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

Tämä korvaa kaikki muut kuin ascii-merkit lähimmällä ascii-ekvivalentilla tai vain ohittaa merkin, jos mikään ei ole sopivaa . On tarpeeksi hyvä moniin tarkoituksiin …

Vastaus

Sinun tulisi muuntaa Unicode-merkkijonosi (jotka on tehty merkkeistä, yksikkö erotettu muistin koosta) tavuiksi käyttämällä asianmukaista koodausta. ennen kuin teet mitään I / O: ta sen kanssa.

Oletusarvon mukaan Python yrittää koodata Unicode-merkkijonosi käyttämällä ASCII-koodausta kirjoittaessasi stdout-tiedostoon (ts. print ), mutta tämä koodaus ei voi edustaa kaikkia Unicode-merkkejä, minkä vuoksi saat virheilmoituksen: ”” ascii ”-koodekki ei voi” koodata merkkiä ”. Melko eksplisiittinen.

Sinun tulisi valita oikea koodaus ja koodata Unicode-merkkijonosi tällä tavalla. Esimerkiksi UTF-8 on tehokas koodaus, joka pystyy käsittelemään kaikki Unicode-merkit. Olettaen, että foo on Unicode-merkkijono, voit tehdä (ja pitäisi): tulostaa foo.encode (”utf -8 ”) vain foo -tulostimen sijaan. Varmista vain, että päätelaitteesi tai mikä tahansa muu ymmärtää valitsemasi koodauksen.Jälleen: UTF-8 on kuumin koodaus siellä tällaisissa tilanteissa, luultavasti haluat käyttää sitä, ellei sinulla ole kovin erityisiä tarpeita.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *