UnicodeDecodeError: o codec 'ascii' não pode decodificar o byte 0xef na posição 1

106

Estou tendo alguns problemas ao tentar codificar uma string em UTF-8. Tentei várias coisas, incluindo usar string.encode('utf-8')e unicode(string), mas recebo o erro:

UnicodeDecodeError: o codec 'ascii' não pode decodificar o byte 0xef na posição 1: ordinal fora do intervalo (128)

Esta é minha string:

(。・ω・。)ノ

Eu não vejo o que está errado, alguma ideia?

Edit: O problema é que imprimir a string como está não é exibida corretamente. Além disso, este erro quando tento convertê-lo:

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)
Markum
fonte
É apenas uma string normalmente inserida. O mesmo acontece quando tento imprimi-lo.
Markum
Encontro o mesmo quando instalo o pip, e corrijo-o aqui: [instale alguns devel] [1] [1]: stackoverflow.com/questions/17931726/…
BollMose

Respostas:

70

Isso tem a ver com a codificação de seu terminal não sendo definida como UTF-8. Aqui está meu terminal

$ 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
(。・ω・。)ノ
>>> 

No meu terminal, o exemplo funciona com o acima, mas se eu me livrar da LANGconfiguração, não funcionará

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

Consulte os documentos de sua variante do Linux para descobrir como tornar essa mudança permanente.

Nick Craig-Wood
fonte
1
A falta de localidades também pode ser um motivo. Para instalá-los, execute sudo apt-get install language-pack-deou sudo locale-gen de_DE.UTF-8(para localidades alemãs).
Non
Para mim, a variável de ambiente ausente é LC_ALL, e o valor mais simples que corrige isso éC.UTF-8
Robin Winslow
24

experimentar:

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

editar:

'(\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', o que é correto.

então o seu problema deve estar em algum lugar diferente, possivelmente se você tentar fazer algo com ele onde houver uma conversão implícita em andamento (pode ser impressão, gravação em um fluxo ...)

para dizer mais, precisamos ver alguns códigos.

mata
fonte
Ambos voltamUnicodeEncodeError: '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
Tudo o que estou tentando fazer é imprimir a string original em seu formato original, mas consigo (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum
4
o stringé codificado em utf8. se você imprimir, ele apenas enviará os bytes para o fluxo de saída, e se seu terminal não interpretar como utf8, você acabará com lixo. com decodevocê convertê-lo para Unicode, você pode encodefazê-lo novamente para uma codificação que seu terminal entenda.
mata
21

Meu +1 ao comentário de mata em https://stackoverflow.com/a/10561979/1346705 e à demonstração de Nick Craig-Wood. Você decodificou a string corretamente. O problema é com o printcomando, pois ele converte a string Unicode para a codificação do console, e o console não é capaz de exibir a string. Tente escrever a string em um arquivo e veja o resultado usando algum editor decente que suporte 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()

Então você verá (。・ω・。)ノ.

pepr
fonte
10

Se você estiver trabalhando em um host remoto , verifique no /etc/ssh/ssh_configseu PC local .

Quando este arquivo contém uma linha:

SendEnv LANG LC_*

comente-o adicionando #no início da linha. Isso pode ajudar.

Com esta linha, sshenvia variáveis ​​de ambiente relacionadas ao idioma de seu PC para o host remoto . Isso causa muitos problemas.

Tsutomu
fonte
Obrigado! Isso resolveu o problema que eu tive ao instalar pacotes pip com ansible e vagrant
Maritza Esparza
10

Tente definir a codificação padrão do sistema como utf-8no início do script, para que todas as strings sejam codificadas usando-a.

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Andrei Krasutski
fonte
por que precisamos recarregar neste caso?
cadáver em
Isso não funciona no Python 3, conforme explicado aqui . Para mim, a resposta de Tsutomu abaixo funcionou.
Piyush Goel
5

Não há problema em usar o código abaixo no início do script, conforme sugerido por Andrei Krasutski .

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

Mas vou sugerir que você também adicione uma # -*- coding: utf-8 -*linha bem no início do script.

Omitir isso gera erro abaixo no meu caso quando tento executar 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

A seguir está o código presente no basic.pyqual lança o erro acima.

código com erro

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)

Então eu adicionei a # -*- coding: utf-8 -*-linha no topo e executei. Funcionou.

código sem erro

# -*- 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)

Obrigado.

higiênico
fonte
1
Usar #coding: utf-8em vez # -*- coding: utf-8 -*- disso é mais fácil de lembrar. Funciona imediatamente com o Python PEP 263 - Definindo codificações de código-fonte do Python .
Andrei Krasutski
Obrigado pela sugestão. Vou tentar no meu lado e atualizá-lo na resposta.
higiênico
4

Sem problemas com meu terminal. As respostas acima me ajudaram a procurar as direções certas, mas não funcionou para mim até que eu adicionei 'ignore':

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

Conforme indicado no comentário abaixo, isso pode levar a resultados indesejados. OTOH também pode funcionar bem o suficiente para fazer as coisas funcionarem e você não se importa em perder alguns personagens.

kqw
fonte
2
Isso está errado, você está forçando a função lambda de codificação a ignorar a própria codificação, o que significa que você está perdendo caracteres.
Maximiliano Rios
2
Isso resolveu meu problema, onde eu não sabia a codificação original e não me importava em perder alguns caracteres.
Edhowler
2

isso funciona para ubuntu 15.10:

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

Parece que sua string está codificada utf-8, então qual é exatamente o problema? Ou o que você está tentando fazer aqui ..?

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'
wim
fonte
Imprimindo a string original como está (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë, quero que codifique corretamente.
Markum
1

No meu caso, foi causado pelo meu arquivo Unicode sendo salvo com um "BOM". Para resolver isso, abri o arquivo usando o BBEdit e fiz um "Salvar como ..." escolhendo a codificação "Unicode (UTF-8)" e não o que veio com "Unicode (UTF-8, com BOM) "

user336828
fonte
0

Eu estava recebendo o mesmo tipo de erro e descobri que o console não é capaz de exibir a string em outro idioma. Portanto, fiz as alterações de código abaixo para definir default_charset como 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 ])
Azam Khan
fonte
-1

BOM, muitas vezes é BOM para mim

vi o arquivo, use

:set nobomb

e salve-o. Isso quase sempre corrige no meu caso

Olly W
fonte
-1

Eu tive o mesmo erro, com URLs contendo caracteres não ascii (bytes com valores> 128)

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

Funcionou para mim, no Python 2.7, suponho que essa atribuição mudou 'algo' na strrepresentação interna - ou seja, ela força a decodificação correta da sequência de bytes apoiada urle finalmente coloca a string em um utf-8 str com toda a magia em O lugar certo. Unicode em Python é magia negra para mim. Espero que seja útil

Fabiano Tarlao
fonte
-2

eu resolvo esse problema mudando no arquivo settings.py com 'ENGINE': 'django.db.backends.mysql', não use 'ENGINE': 'mysql.connector.django',

user3787102
fonte
@rayryeng Você poderia explicar o motivo de sua edição? Parece mudar completamente o significado do que o OP escreveu, desde recomendar uma configuração específica até recomendar contra ela.
ninguém
@AndrewMedico - Minhas desculpas. Vi que esse post era muito parecido com o outro então acreditei que fossem iguais. Eu vou voltar.
rayryeng
-2

Basta converter o texto explicitamente em string usando str(). Funcionou para mim.

Supratim Samantray
fonte