as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!
Como corrigi-lo?
Em alguns outros aplicativos de blog estáticos baseados em python, a postagem em chinês pode ser publicada com sucesso. Como este aplicativo: http://github.com/vrypan/bucket3 . No meu site http://bc3.brite.biz/ , o post em chinês pode ser publicado com sucesso.
python
python-2.7
chinese-locale
pescador
fonte
fonte
Respostas:
tl; dr / correção rápida
reload
hacks rápidosZen Unicode no Python 2.x - a versão longa
Sem ver a fonte, é difícil conhecer a causa raiz, então terei que falar em geral.
UnicodeDecodeError: 'ascii' codec can't decode byte
geralmente acontece quando você tenta converter um Python 2.xstr
que contém não-ASCII em uma cadeia de caracteres Unicode sem especificar a codificação da cadeia de caracteres original.Em resumo, as cadeias Unicode são um tipo totalmente separado de cadeia Python que não contém nenhuma codificação. Eles contêm apenas códigos de ponto Unicode e, portanto, podem conter qualquer ponto Unicode de todo o espectro. As strings contêm texto codificado, como UTF-8, UTF-16, ISO-8895-1, GBK, Big5 etc. As strings são decodificadas para Unicode e Unicodes são codificadas para strings . Arquivos e dados de texto são sempre transferidos em cadeias codificadas.
Os autores do módulo Markdown provavelmente usam
unicode()
(onde a exceção é lançada) como uma porta de qualidade para o restante do código - ele converterá ASCII ou reorganizará as cadeias Unicodes existentes em uma nova cadeia Unicode. Os autores do Markdown não sabem a codificação da sequência de entrada, portanto, você decodificará as seqüências de caracteres em strings Unicode antes de passar para o Markdown.As strings Unicode podem ser declaradas no seu código usando o
u
prefixo das strings. Por exemploAs strings Unicode também podem vir de arquivos, bancos de dados e módulos de rede. Quando isso acontece, você não precisa se preocupar com a codificação.
Pegadinhas
A conversão de
str
para Unicode pode ocorrer mesmo quando você não chama explicitamenteunicode()
.Os seguintes cenários causam
UnicodeDecodeError
exceções:Exemplos
No diagrama a seguir, você pode ver como a palavra
café
foi codificada na codificação "UTF-8" ou "Cp1252", dependendo do tipo de terminal. Nos dois exemplos,caf
são apenas ascii regulares. Em UTF-8,é
é codificado usando dois bytes. Em "Cp1252", é 0xE9 (que também é o valor do ponto Unicode (não é coincidência)). O corretodecode()
é chamado e a conversão para um Python Unicode é bem-sucedida:Neste diagrama,
decode()
é chamado comascii
(que é o mesmo que chamarunicode()
sem uma codificação fornecida). Como o ASCII não pode conter bytes maiores que0x7F
, isso gerará umaUnicodeDecodeError
exceção:O sanduíche Unicode
É uma boa prática formar um sanduíche Unicode no seu código, onde você decodifica todos os dados recebidos em cadeias Unicode, trabalha com Unicodes e depois codifica para
str
s na saída. Isso evita que você se preocupe com a codificação de strings no meio do seu código.Entrada / decodificação
Código fonte
Se você precisar inserir não-ASCII em seu código-fonte, basta criar cadeias Unicode prefixando-as com a
u
. Por exemploPara permitir que o Python decodifique seu código-fonte, você precisará adicionar um cabeçalho de codificação para corresponder à codificação real do seu arquivo. Por exemplo, se seu arquivo foi codificado como 'UTF-8', você usaria:
Isso é necessário apenas quando você possui código não ASCII .
arquivos
Normalmente, dados não ASCII são recebidos de um arquivo. O
io
módulo fornece um TextWrapper que decodifica seu arquivo rapidamente, usando um dadoencoding
. Você deve usar a codificação correta para o arquivo - ele não pode ser facilmente adivinhado. Por exemplo, para um arquivo UTF-8:my_unicode_string
seria adequado para passar para Markdown. Se forUnicodeDecodeError
daread()
linha, você provavelmente já usou o valor de codificação errado.Arquivos CSV
O módulo CSV do Python 2.7 não suporta caracteres não ASCII 😩. A ajuda está disponível, no entanto, com https://pypi.python.org/pypi/backports.csv .
Use-o como acima, mas passe o arquivo aberto para ele:
Bases de dados
A maioria dos drivers de banco de dados Python pode retornar dados em Unicode, mas geralmente requer um pouco de configuração. Sempre use seqüências de caracteres Unicode para consultas SQL.
MySQLNa cadeia de conexão, adicione:
Por exemplo
PostgreSQLAdicionar:
HTTP
As páginas da Web podem ser codificadas em praticamente qualquer codificação. O
Content-type
cabeçalho deve conter umcharset
campo para sugerir a codificação. O conteúdo pode ser decodificado manualmente contra esse valor. Como alternativa, Python-Requests retorna Unicodes emresponse.text
.Manualmente
Se você precisar decodificar cadeias manualmente, pode simplesmente fazer
my_string.decode(encoding)
, ondeencoding
está a codificação apropriada. Os codecs suportados pelo Python 2.x são fornecidos aqui: Codificações padrão . Novamente, se você receberUnicodeDecodeError
, provavelmente terá a codificação errada.A carne do sanduíche
Trabalhe com Unicodes como faria com strs normais.
Resultado
stdout / impressão
print
escreve através do fluxo stdout. O Python tenta configurar um codificador no stdout para que os Unicodes sejam codificados na codificação do console. Por exemplo, se um shell do Linuxlocale
foren_GB.UTF-8
, a saída será codificada paraUTF-8
. No Windows, você estará limitado a uma página de código de 8 bits.Um console configurado incorretamente, como código de idioma corrompido, pode levar a erros de impressão inesperados.
PYTHONIOENCODING
A variável de ambiente pode forçar a codificação para stdout.arquivos
Assim como a entrada,
io.open
pode ser usado para converter transparentemente Unicodes em seqüências de bytes codificadas.Base de dados
A mesma configuração para leitura permitirá que Unicodes sejam gravados diretamente.
Python 3
O Python 3 não é mais capaz de Unicode do que o Python 2.x, no entanto, é um pouco menos confuso sobre o assunto. Por exemplo, o regular
str
agora é uma string Unicode e o antigostr
agorabytes
.A codificação padrão é UTF-8, portanto, se você for
.decode()
uma sequência de bytes sem fornecer uma codificação, o Python 3 usará a codificação UTF-8. Isso provavelmente corrige 50% dos problemas de Unicode das pessoas.Além disso,
open()
opera no modo de texto por padrão, então retorna decodificadostr
(Unicode). A codificação é derivada do código de idioma, que tende a ser UTF-8 em sistemas Un * x ou uma página de código de 8 bits, como windows-1251, nas caixas do Windows.Por que você não deve usar
sys.setdefaultencoding('utf8')
É um hack desagradável (há uma razão para você usar
reload
) que apenas mascara problemas e dificulta sua migração para o Python 3.x. Entenda o problema, corrija a causa raiz e aproveite o Unicode zen. Consulte Por que NÃO devemos usar sys.setdefaultencoding ("utf-8") em um script py? para mais detalhesfonte
io.open
para ler / gravar arquivos, usefrom __future__ import unicode_literals
, configure outras entradas / saídas de dados (por exemplo, bancos de dados) para usar unicode.PYTHONIOENCODING=utf-8
. Se isso não corrigir, você precisará entrar em contato com o autor do script para corrigir o código.Finalmente eu entendi:
Deixe-me ver:
A descrição acima mostra que a codificação padrão do python é
utf8
. Então o erro não existe mais.fonte
str
, portanto, não está atrasada lá. No Python 2.x, o Unicode estava em um estado de transição, portanto, seria perigoso assumir uma codificação ao converter bytes em Unicodes. Portanto, a codificação padrão do ASCII do Py2 foi uma escolha deliberada e por que alterar a codificação padrão requer o hack deliberado do recarregamentosys
. A maneira correta de banir os erros de codificação no Py2 é decodificar e codificar de forma inequívoca (byte) as seqüências de caracteres em Unicode, quando as conversões forem necessárias - e não apenas presumir que as strings são codificadas em UTF-8.Este é o clássico "problema unicode". Acredito que explicar isso está além do escopo de uma resposta StackOverflow para explicar completamente o que está acontecendo.
Está bem explicado aqui .
Em um resumo muito breve, você passou algo que está sendo interpretado como uma sequência de bytes para algo que precisa decodificá-lo em caracteres Unicode, mas o codec padrão (ascii) está falhando.
A apresentação que eu apontei para você fornece conselhos para evitar isso. Faça do seu código um "sanduíche unicode". No Python 2, o uso de
from __future__ import unicode_literals
ajuda.Atualização: como o código pode ser corrigido:
OK - na sua variável "fonte" você tem alguns bytes. Não está claro em sua pergunta como eles chegaram lá - talvez você os leia em um formulário da Web? De qualquer forma, eles não são codificados com ascii, mas o python está tentando convertê-los em unicode, assumindo que eles são. Você precisa dizer explicitamente qual é a codificação. Isso significa que você precisa saber qual é a codificação! Isso nem sempre é fácil e depende inteiramente de onde essa string veio. Você pode experimentar algumas codificações comuns - por exemplo, UTF-8. Você diz a unicode () a codificação como um segundo parâmetro:
fonte
currentFile = open(filename, 'rt', encoding='latin1')
oucurrentFile = open(filename, 'rt', encoding='utf-8')
- veja aqui: stackoverflow.com/a/23917799/2047442Em alguns casos, quando você verifica sua codificação padrão (
print sys.getdefaultencoding()
), retorna que você está usando ASCII. Se você mudar para UTF-8, não funcionará, dependendo do conteúdo da sua variável. Eu encontrei outra maneira:fonte
reload(sys)
é usado por esse motivo específico.Eu estava procurando resolver a seguinte mensagem de erro:
Finalmente consertei isso especificando 'codificação':
Gostaria que pudesse ajudá-lo também.
fonte
Causa deste erro: input_string deve ser unicode, mas str foi fornecido
Causa deste erro: tentando converter unicode input_string em unicode
Portanto, verifique primeiro se seu input_string é
str
e converta para unicode, se necessário:Em segundo lugar, o texto acima apenas altera o tipo, mas não remove caracteres não ascii. Se você deseja remover caracteres não-ascii:
fonte
Acho que o melhor é sempre converter para unicode - mas isso é difícil de conseguir, porque na prática você teria que verificar e converter todos os argumentos em todas as funções e métodos que você escreve, incluindo alguma forma de processamento de string.
Então, eu vim com a seguinte abordagem para garantir cadeias unicodes ou bytes, de qualquer entrada. Em resumo, inclua e use as seguintes lambdas:
Exemplos:
Aqui está mais um raciocínio sobre isso .
fonte
print unicode(u'Zürich', encoding="UTF-8")
e depois reclame "Mas, surpreendentemente, você não pode codificar unicode ext em UTF8".unicode()
não codifica; decodifica e você não pode decodificar um Unicode - já está decodificado!Para resolver isso no nível do sistema operacional em uma instalação do Ubuntu, verifique o seguinte:
Se você pegar
ao invés de
então defina
LC_CTYPE
eLC_ALL
assim:fonte
Codificar converte um objeto unicode em um objeto de sequência. Eu acho que você está tentando codificar um objeto string. primeiro converta seu resultado em objeto unicode e depois codifique esse objeto unicode em 'utf-8'. por exemplo
fonte
Eu tive o mesmo problema, mas não funcionou no Python 3. Segui isso e resolvi o meu problema:
Você precisa definir a codificação quando estiver lendo / gravando o arquivo.
fonte
Recebi o mesmo erro e isso resolveu o meu erro. Obrigado! python 2 e python 3 diferentes no manuseio unicode estão tornando os arquivos em pickup bastante incompatíveis para carregar. Portanto, use o argumento de codificação python pickle. O link abaixo me ajudou a resolver o problema semelhante quando estava tentando abrir dados em conserva do meu python 3.7, enquanto meu arquivo foi salvo originalmente na versão do python 2.x. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Copio a função load_pickle no meu script e chamei load_pickle (pickle_file) durante o carregamento do meu input_data assim:
A função load_pickle está aqui:
fonte
load_pickle
função em sua resposta.Isso funcionou para mim:
fonte
Em resumo, para garantir o manuseio unicode adequado no Python 2:
io.open
para ler / gravar arquivosfrom __future__ import unicode_literals
print(text.encode('ascii', 'replace').decode())
Para explicações, consulte a resposta detalhada de @Alastair McCormack .
fonte
io.open(path, 'r', encoding='utf-8')
para ler arquivos codificados em utf-8.Eu tive o mesmo erro, com URLs contendo caracteres não-ascii (bytes com valores> 128), minha solução:
Nota: utf-8, utf8 são simplesmente aliases. Usar apenas 'utf8' ou 'utf-8' deve funcionar da mesma maneira
No meu caso, trabalhei para mim, no Python 2.7, suponho que essa atribuição tenha alterado 'algo' na
str
representação interna - ou seja, força a decodificação correta da sequência de bytes de backupurl
e, finalmente, coloca a string em um utf-8str
com toda a magia no lugar certo. Unicode em Python é magia negra para mim. Espero que seja útilfonte
Eu tive o mesmo problema com a string "Pastelería Mallorca" e resolvi com:
fonte
Em um projeto Django (1.9.10) / Python 2.7.5, tenho
`UnicodeDecodeError
exceções frequentes ; principalmente quando tento alimentar cadeias unicode no log. Eu criei uma função auxiliar para objetos arbitrários basicamente para formatar cadeias ASCII de 8 bits e substituir qualquer caractere que não esteja na tabela para '?'. Eu acho que não é a melhor solução, mas como a codificação padrão é ascii (e eu não quero alterá-la), ela fará:fonte
Este erro ocorre quando há alguns caracteres não ASCII em nossa string e estamos executando quaisquer operações nessa string sem decodificação adequada. Isso me ajudou a resolver meu problema. Estou lendo um arquivo CSV com ID de colunas, caracteres de texto e decodificação, como abaixo:
fonte
Aqui está a minha solução, basta adicionar a codificação.
with open(file, encoding='utf8') as f
E como a leitura do arquivo de luva levará muito tempo, recomendo que ele seja um arquivo numpy. Quando o tempo de netx você lê os pesos de incorporação, ele economiza seu tempo.
Gist link: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227
fonte
Especifique: # encoding = utf-8 na parte superior do seu arquivo Python, deve corrigir o problema
fonte