Quando tento imprimir uma seqüência de caracteres Unicode em um console do Windows, recebo um UnicodeEncodeError: 'charmap' codec can't encode character ....
erro. Suponho que isso ocorre porque o console do Windows não aceita caracteres somente Unicode. Qual é a melhor maneira de contornar isso? Existe alguma maneira de fazer o Python imprimir automaticamente um em ?
vez de falhar nessa situação?
Edit: Estou usando o Python 2.5.
Nota: a resposta @ LasseV.Karlsen com a marca de seleção está desatualizada (a partir de 2008). Por favor, use as soluções / respostas / sugestões abaixo com cuidado !!
A resposta @JFSebastian é mais relevante a partir de hoje (6 de janeiro de 2016).
Respostas:
Nota: Esta resposta está desatualizada (a partir de 2008). Por favor, use a solução abaixo com cuidado !!
Aqui está uma página que detalha o problema e uma solução (procure na página o texto Encapsulando sys.stdout em uma instância ):
PrintFails - Python Wiki
Aqui está um trecho de código dessa página:
Há mais informações nessa página, vale a pena ler.
fonte
sys.stdout
, ele imprime as coisas erradas. Por exemplo,u'\u2013'
torna-se emû
vez de um traço.cp437
diferente da página de códigos do Windows ANSI, comocp1252
. O código não corrige oUnicodeEncodeError: 'charmap' codec can't encode character
erro e pode levar ao mojibake, por exemplo,ا©
é silenciosamente substituído por╪º⌐
.Atualização: Python 3.6 implementa PEP 528: Altere a codificação do console do Windows para UTF-8 : o console padrão no Windows agora aceitará todos os caracteres Unicode. Internamente, ele usa a mesma API Unicode que o
win-unicode-console
pacote mencionado abaixo .print(unicode_string)
deve funcionar agora.O erro significa que os caracteres Unicode que você está tentando imprimir não podem ser representados usando a
chcp
codificação de caracteres do console atual ( ). A página de código geralmente é uma codificação de 8 bits,cp437
que pode representar apenas ~ 0x100 caracteres a partir de ~ 1M caracteres Unicode:O console do Windows aceita caracteres Unicode e pode até exibi-los (somente BMP) se a fonte correspondente estiver configurada .
WriteConsoleW()
A API deve ser usada conforme sugerido na resposta de @Daira Hopwood . Pode ser chamado de forma transparente, ou seja, você não precisa e não deve modificar seus scripts se usar owin-unicode-console
pacote :Veja Qual é o problema do Python 3.4, Unicode, diferentes idiomas e Windows?
Se for suficiente substituir todos os caracteres não codificáveis por
?
no seu caso, você poderá definirPYTHONIOENCODING
envvar :No Python 3.6+, a codificação especificada por
PYTHONIOENCODING
envvar é ignorada para buffers de console interativos, a menos quePYTHONLEGACYWINDOWSIOENCODING
envvar seja definido como uma seqüência de caracteres não vazia.fonte
print('\u4E01')
,print('\u6b63')
).Apesar das outras respostas plausíveis que sugerem alterar a página de códigos para 65001, isso não funciona . (Além disso, alterar a codificação padrão usando não
sys.setdefaultencoding
é uma boa ideia .)Veja esta pergunta para detalhes e código que funciona.
fonte
win-unicode-console
Pacote Python (com base em seu código) permite evitar modificar seu script se ele imprime Unicode diretamente usandopy -mrun your_script.py
comandos .Se você não está interessado em obter uma representação confiável do (s) caractere (s) incorreto (s), use algo assim (trabalhando com python> = 2.6, incluindo 3.x):
Os caracteres incorretos na string serão convertidos em uma representação que pode ser impressa pelo console do Windows.
fonte
.encode('utf8').decode(sys.stdout.encoding)
leva a mojibake por exemplo,u"\N{EM DASH}".encode('utf-8').decode('cp437')
->ΓÇö
print(s.encode('utf-8'))
pode ser uma maneira melhor de evitar erros do compilador. Em vez disso, você obtém a saída \ xNN para caracteres não imprimíveis, o suficiente para minhas mensagens de diagnóstico.O código abaixo fará a saída do Python para o console como UTF-8, mesmo no Windows.
O console exibirá os caracteres bem no Windows 7, mas no Windows XP não os exibirá bem, mas pelo menos funcionará e o mais importante: você terá uma saída consistente do seu script em todas as plataformas. Você poderá redirecionar a saída para um arquivo.
O código abaixo foi testado com o Python 2.6 no Windows.
fonte
import win32console
fora de umtry
e depois você faz isso condicionalmente dentro de umtry
? Não é esse tipo de inútil (o primeiroimport
)Basta digitar este código na linha de comando antes de executar o script python:
fonte
Como a resposta de Giampaolo Rodolà, mas ainda mais suja: eu realmente pretendo passar muito tempo (em breve) compreendendo todo o assunto das codificações e como elas se aplicam aos consoles Windoze,
No momento, eu só queria o sthg, o que significaria que o meu programa não iria entrar em colapso e o que eu entendi ... e também que não envolvia a importação de muitos módulos exóticos (em particular eu estou usando o Jython, na metade do tempo um Python acaba por não estar disponível).
NB "pr" é mais curto para digitar do que "print" (e um pouco mais curto para digitar que "safeprint") ...!
fonte
Para o Python 2, tente:
Para o Python 3, tente:
Ou tente win-unicode-console:
fonte
TL; DR:
Eu me deparei com isso sozinho, trabalhando em um bot do Twitch chat (IRC). (Python 2.7 mais recente)
Eu queria analisar as mensagens de bate-papo para responder ...
mas também imprima-os com segurança no console em um formato legível por humanos:
Isso corrigiu o problema dos
UnicodeEncodeError: 'charmap'
erros de lançamento do bot e substituiu os caracteres unicode por?
.fonte
A causa do seu problema NÃO é o console do Win que não está disposto a aceitar Unicode (como faz isso desde que eu acho que o Win2k por padrão). É a codificação padrão do sistema. Experimente este código e veja o que ele oferece:
se ele diz ascii, aí está sua causa ;-) Você precisa criar um arquivo chamado sitecustomize.py e colocá-lo no caminho do python (eu o coloco em /usr/lib/python2.5/site-packages, mas isso é diferente em Win - é c: \ python \ lib \ site-packages ou algo assim), com o seguinte conteúdo:
e talvez você também queira especificar a codificação em seus arquivos:
Edit: mais informações podem ser encontradas no excelente livro Dive into Python
fonte
Tipo de parente na resposta de JF Sebastian, mas mais direto.
Se você estiver tendo esse problema ao imprimir no console / terminal, faça o seguinte:
fonte
set PYTHONIOENCODING=UTF-8
pode levar ao mojibake se o console usar uma codificação diferente, como cp437.cp65001
tem vários problemas . Para imprimir Unicode no console do Windows, a API Unicode deve ser usada (WriteConsoleW()
), como sugerido na minha resposta, ondePYTHONIOENCODING
é usada apenas para substituir caracteres que não podem ser representados na página de código OEM atual por?
(WriteConsoleW()
funciona mesmo para esses caracteres).PYTHONIOENCODING
pode ser usado se a saída for redirecionada para um arquivo.Python 3.6 windows7: Há várias maneiras de iniciar um python: você pode usar o console python (que possui um logotipo python) ou o console do windows (está escrito cmd.exe).
Não consegui imprimir caracteres utf8 no console do Windows. A impressão de caracteres utf-8 me gera este erro:
Depois de tentar e não entender a resposta acima, descobri que era apenas um problema de configuração. Clique com o botão direito do mouse na parte superior das janelas do console do cmd e, na guia,
font
escolha lucida console.fonte
James Sulak perguntou:
Outras soluções recomendam que tentemos modificar o ambiente do Windows ou substituir a
print()
função do Python . A resposta abaixo se aproxima mais do cumprimento da solicitação de Sulak.No Windows 7, o Python 3.5 pode ser criado para imprimir Unicode sem gerar a
UnicodeEncodeError
seguinte:No lugar de:
print(text)
substitute:
print(str(text).encode('utf-8'))
Em vez de lançar uma exceção, o Python agora exibe caracteres Unicode não imprimíveis como códigos hexadecimais \ xNN , por exemplo:
\ N \ xe2 \ x80 \ x99 \ xc3 \ xa9tait mais do que hal \ xe2 \ x80 \ x99un point noir
Ao invés de
Halmalo n'était plus qu'un point noir
É verdade que o último é preferível ceteris paribus , mas, caso contrário, o primeiro é completamente preciso para mensagens de diagnóstico. Como exibe Unicode como valores de bytes literais, o primeiro também pode ajudar no diagnóstico de problemas de codificação / decodificação.
Nota: A
str()
chamada acima é necessária porque, de outra forma,encode()
faz com que o Python rejeite um caractere Unicode como uma tupla de números.fonte