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')dà 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.