UnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xef nella posizione 1


106

Sto riscontrando alcuni problemi nel tentativo di codificare una stringa in UTF-8. Ho provato numerose cose, incluso l'uso di string.encode('utf-8')e unicode(string), ma ottengo l'errore:

UnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xef nella posizione 1: ordinale non compreso nell'intervallo (128)

Questa è la mia stringa:

(。・ω・。)ノ

Non vedo cosa sta andando storto, qualche idea?

Modifica: il problema è che la stampa della stringa così com'è non viene visualizzata correttamente. Inoltre, questo errore quando provo a convertirlo:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)

È solo una stringa normalmente inserita. Lo stesso accade quando provo a stamparlo.
Markum

Mi capita di incontrare lo stesso quando PiP installare, e risolvere il problema da qui: [installare alcuni devel] [1] [1]: stackoverflow.com/questions/17931726/...
BollMose

Risposte:


70

Questo ha a che fare con la codifica del tuo terminale non impostata su UTF-8. Ecco il mio terminale

$ echo $LANG
en_GB.UTF-8
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> 

Sul mio terminale l'esempio funziona con quanto sopra, ma se mi sbarazzo LANGdell'impostazione, non funzionerà

$ unset LANG
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
>>> 

Consulta la documentazione della tua variante Linux per scoprire come rendere permanente questa modifica.


1
Anche le località mancanti potrebbero essere un motivo. Per installarli eseguire sudo apt-get install language-pack-deo sudo locale-gen de_DE.UTF-8(per le lingue tedesche).
Non

Per me, la variabile di ambiente mancante è LC_ALL, e il valore più semplice che potrebbe risolverlo èC.UTF-8
Robin Winslow

24

provare:

string.decode('utf-8')  # or:
unicode(string, 'utf-8')

modificare:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')u'(\uff61\uff65\u03c9\uff65\uff61)\uff89', che è corretto.

quindi il tuo problema deve essere in qualche altro posto, possibilmente se provi a fare qualcosa con esso se è in corso una conversione implicita (potrebbe essere la stampa, la scrittura in un flusso ...)

per dire di più dovremo vedere del codice.


Entrambi tornanoUnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
Markum

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
Markum

1
Tutto quello che cerco di fare è stampare la stringa originale nel suo formato originale, ma ottengo (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum

4
la stringè utf8-encoded. se lo stampi, invia semplicemente i byte al flusso di output e se il tuo terminale non lo interpreta come utf8 finisci con la spazzatura. con decodelo converti in unicode, quindi puoi di encodenuovo in una codifica che il tuo terminale capisce.
mata

21

Il mio +1 al commento di mata su https://stackoverflow.com/a/10561979/1346705 e alla dimostrazione di Nick Craig-Wood. Hai decodificato correttamente la stringa. Il problema è con il printcomando poiché converte la stringa Unicode nella codifica della console e la console non è in grado di visualizzare la stringa. Prova a scrivere la stringa in un file e guarda il risultato usando un editor decente che supporti Unicode:

import codecs

s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
s1 = s.decode('utf-8')
f = codecs.open('out.txt', 'w', encoding='utf-8')
f.write(s1)
f.close()

Allora vedrai (。・ω・。)ノ.


10

Se stai lavorando su un host remoto , guarda /etc/ssh/ssh_configsul tuo PC locale .

Quando questo file contiene una riga:

SendEnv LANG LC_*

commentalo aggiungendo #all'inizio della riga. Potrebbe aiutare.

Con questa riga, sshinvia le variabili di ambiente relative alla lingua del PC all'host remoto . Causa molti problemi.


Grazie! Questi hanno risolto il problema che avevo installando i pacchetti pip con ansible e vagrant
Maritza Esparza


5

Va bene usare il codice seguente nella parte superiore dello script come suggerito da Andrei Krasutski .

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Ma ti suggerirò di aggiungere anche una # -*- coding: utf-8 -*riga all'inizio dello script.

Ometterlo genera l'errore di seguito nel mio caso quando provo a eseguire basic.py.

$ python basic.py
  File "01_basic.py", line 14
SyntaxError: Non-ASCII character '\xd9' in file basic.py on line 14, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Quello che segue è il codice presente in basic.pycui genera l'errore precedente.

codice con errore

from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Poi ho aggiunto la # -*- coding: utf-8 -*-linea in alto ed eseguito. Ha funzionato.

codice senza errori

# -*- coding: utf-8 -*-
from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Grazie.


1
Usare #coding: utf-8invece di # -*- coding: utf-8 -*- questo è più facile da ricordare. Funziona fuori dagli schemi con Python PEP 263 - Definizione delle codifiche del codice sorgente Python .
Andrei Krasutski

Grazie per il suggerimento. Proverò alla mia fine e lo aggiornerò nella risposta.
Hygull

4

Nessun problema con il mio terminale. Le risposte di cui sopra mi hanno aiutato a guardare nelle giuste direzioni, ma non ha funzionato per me fino a quando non ho aggiunto 'ignore':

fix_encoding = lambda s: s.decode('utf8', 'ignore')

Come indicato nel commento qui sotto, ciò può portare a risultati indesiderati. OTOH potrebbe anche fare il trucco abbastanza bene da far funzionare le cose e non ti interessa perdere alcuni personaggi.


2
Questo è sbagliato, stai costringendo la tua funzione lambda di codifica a ignorare la codifica stessa, il che significa che stai perdendo caratteri.
Maximiliano Rios

2
Questo ha risolto il mio problema, in cui non conoscevo la codifica originale e non mi importava di perdere alcuni caratteri.
Edhowler

2

questo funziona per Ubuntu 15.10:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales

1

Sembra che la tua stringa sia codificata utf-8, quindi qual è esattamente il problema? O cosa stai cercando di fare qui ..?

Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> s2 = u'(。・ω・。)ノ'
>>> s2 == s1
True
>>> s2
u'(\uff61\uff65\u03c9\uff65\uff61)\uff89'

Stampando la stringa originale così com'è (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë, voglio che codifichi correttamente.
Markum

1

Nel mio caso, è stato causato dal salvataggio del mio file Unicode con un "BOM". Per risolvere questo problema, ho aperto il file utilizzando BBEdit e ho eseguito un "Salva con nome ..." scegliendo per la codifica "Unicode (UTF-8)" e non quello con cui veniva fornito che era "Unicode (UTF-8, con BOM) "


0

Ricevo lo stesso tipo di errore e ho scoperto che la console non è in grado di visualizzare la stringa in un'altra lingua. Quindi ho apportato le seguenti modifiche al codice per impostare default_charset come UTF-8.

data_head = [('\x81\xa1\x8fo\x89\xef\x82\xa2\x95\xdb\x8f\xd8\x90\xa7\x93x\x81\xcb3\x8c\x8e\x8cp\x91\xb1\x92\x86(\x81\x86\x81\xde\x81\x85)\x81\xa1\x8f\x89\x89\xf1\x88\xc8\x8aO\x81A\x82\xa8\x8b\xe0\x82\xcc\x90S\x94z\x82\xcd\x88\xea\x90\xd8\x95s\x97v\x81\xa1\x83}\x83b\x83v\x82\xcc\x82\xa8\x8e\x8e\x82\xb5\x95\xdb\x8c\xaf\x82\xc5\x8fo\x89\xef\x82\xa2\x8am\x92\xe8\x81\xa1', 'shift_jis')]
default_charset = 'UTF-8' #can also try 'ascii' or other unicode type
print ''.join([ unicode(lin[0], lin[1] or default_charset) for lin in data_head ])


-1

BOM, è così spesso BOM per me

vi il file, usate

:set nobomb

e salvalo. Questo quasi sempre lo risolve nel mio caso


-1

Ho avuto lo stesso errore, con URL contenenti caratteri non ASCII (byte con valori> 128)

url = url.decode('utf8').encode('utf-8')

Ha funzionato per me, in Python 2.7, suppongo che questa assegnazione abbia cambiato 'qualcosa' nella strrappresentazione interna - cioè, forza la giusta decodifica della sequenza di byte sostenuta urle infine inserisce la stringa in un utf-8 str con tutta la magia in il posto giusto. Unicode in Python è magia nera per me. Spero utile


-2

risolvo il problema cambiando nel file settings.py con 'ENGINE': 'django.db.backends.mysql', non usare 'ENGINE': 'mysql.connector.django',


@rayryeng Potresti spiegare il motivo della tua modifica? Sembra cambiare completamente il significato di ciò che ha scritto il PO, dal raccomandare una particolare impostazione al raccomandare contro di essa.
nessuno il

@AndrewMedico - Le mie scuse. Ho visto che questo post era molto simile a un altro quindi ho creduto che fossero la stessa cosa. Tornerò indietro.
rayryeng

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.