Eu tenho muitos problemas de "não é possível codificar" e "não é possível decodificar" com o Python quando executo meus aplicativos no console. Mas no Eclipse PyDev IDE, a codificação de caracteres padrão é definida como UTF-8 , e eu estou bem.
Eu procurei ao redor para definir a codificação padrão, e as pessoas dizem que o Python exclui a sys.setdefaultencoding
função na inicialização, e não podemos usá-la.
Então, qual é a melhor solução para isso?
The best solution is to learn to use encode and decode correctly instead of using hacks.
Isso certamente foi possível com o python2 ao custo de sempre lembrar-se de fazê-lo / de forma consistente usando sua própria interface. Minha experiência sugere que isso se torna altamente problemático quando você está escrevendo um código com o qual deseja trabalhar com python2 e python3.Respostas:
Aqui está um método mais simples (hack) que devolve a
setdefaultencoding()
função que foi excluída desys
:(Nota para o Python 3.4+:
reload()
está naimportlib
biblioteca.)Porém, isso não é uma coisa segura a se fazer : obviamente é um hack, pois
sys.setdefaultencoding()
é propositadamente removido desys
quando o Python é iniciado. A reativação e a alteração da codificação padrão podem interromper o código que depende do padrão ASCII (esse código pode ser de terceiros, o que geralmente tornaria a correção impossível ou perigosa).fonte
LC_CTYPE
(ou em um aplicativo, verifique se está definido corretamente e aborte com uma mensagem de erro significativa).LC_CTYPE=C python -c 'import locale; print( locale.getpreferredencoding())'
Se você receber esse erro ao tentar canalizar / redirecionar a saída do seu script
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)
Apenas exporte PYTHONIOENCODING no console e execute seu código.
export PYTHONIOENCODING=utf8
fonte
LC_CTYPE
como algo sensato. Faz todos os outros programas felizes também.PYTHONIOENCODING=utf8
não é o padrão. Isso faz com que scripts de quebrar só porqueLC_ALL=C
Set LC_CTYPE to something sensible instead
Esta é uma sugestão razoável. Isso não funciona tão bem quando você está tentando distribuir código que funciona apenas no sistema de outra pessoa.C.utf8
código de idioma para fornecer que a C. glibc upstream mais sensata esteja trabalhando para adicioná-lo, então talvez não devamos culpar o Python por respeitar as configurações de código de idioma \…?A) Para controlar a
sys.getdefaultencoding()
saída:ascii
Então
e
utf-16-be
Você pode colocar seu sitecustomize.py mais alto no seu
PYTHONPATH
.Você também pode tentar
reload(sys).setdefaultencoding
por @EOLB) Para controlar
stdin.encoding
estdout.encoding
você deseja definirPYTHONIOENCODING
:ascii ascii
Então
utf-16-be utf-16-be
Finalmente: você pode usar A) ou B) ou ambos!
fonte
from __future__ import unicode_literals
ver discussãoA partir do PyDev 3.4.1, a codificação padrão não está mais sendo alterada. Veja este ticket para mais detalhes.
Para versões anteriores, uma solução é garantir que o PyDev não seja executado com UTF-8 como a codificação padrão. No Eclipse, execute as configurações de diálogo ("configurações de execução", se bem me lembro); você pode escolher a codificação padrão na guia comum. Altere-o para US-ASCII se desejar que esses erros sejam 'precoces' (em outras palavras: no seu ambiente PyDev). Veja também uma postagem original do blog para esta solução alternativa .
fonte
Em relação ao python2 (e somente python2), algumas das respostas anteriores contam com o seguinte hack:
É desencorajado usá-lo (marque isto ou isto )
No meu caso, ele vem com um efeito colateral: estou usando notebooks ipython e, depois que executo o código, a função 'print' não funciona mais. Acho que haveria solução para isso, mas ainda acho que usar o hack não deve ser a opção correta.
Depois de tentar muitas opções, a que funcionou para mim estava usando o mesmo código no
sitecustomize.py
, onde esse trecho de código deve estar . Após avaliar esse módulo, a função setdefaultencoding é removida do sys.Portanto, a solução é anexar ao arquivo
/usr/lib/python2.7/sitecustomize.py
o código:Quando eu uso o virtualenvwrapper, o arquivo que eu edito é
~/.virtualenvs/venv-name/lib/python2.7/sitecustomize.py
.E quando eu uso com notebooks python e conda, é
~/anaconda2/lib/python2.7/sitecustomize.py
fonte
Há uma publicação perspicaz no blog sobre isso.
Consulte https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/ .
Parafrasco seu conteúdo abaixo.
No python 2, que não foi tão fortemente digitado em relação à codificação de cadeias, você pode executar operações em cadeias codificadas de maneira diferente e obter êxito. Por exemplo, o seguinte retornaria
True
.Isso seria válido para todas as strings (normais, sem prefixo) codificadas
sys.getdefaultencoding()
, que eram padronizadasascii
, mas não para outras.A codificação padrão deveria ser alterada em todo o sistema
site.py
, mas não em outro lugar. Os hacks (também apresentados aqui) para configurá-lo nos módulos do usuário eram apenas isso: hacks, não a solução.O Python 3 alterou a codificação do sistema para o padrão utf-8 (quando LC_CTYPE reconhece o unicode), mas o problema fundamental foi resolvido com o requisito de codificar explicitamente cadeias de "bytes" sempre que usadas com cadeias de caracteres unicode.
fonte
Primeiro:
reload(sys)
configurar uma codificação padrão aleatória apenas para a necessidade de um fluxo de terminal de saída é uma prática recomendada.reload
geralmente muda as coisas no sys que foram implementadas dependendo do ambiente - por exemplo, sys.stdin / stdout streams, sys.excepthook, etc.Resolvendo o problema de codificação no stdout
A melhor solução que eu conheço para resolver o problema de codificação de
print
strings unicode e além de asciistr
(por exemplo, de literais) em sys.stdout é: cuidar de um sys.stdout (objeto semelhante a arquivo) que seja capaz e opcionalmente tolerante em relação às necessidades:Quando
sys.stdout.encoding
éNone
por algum motivo, ou não-existente, ou erroneamente falsa ou "menos" do que o que o terminal stdout ou transmitir realmente é capaz de, em seguida, tentar fornecer uma correta.encoding
atributo. Por fim, substituindosys.stdout & sys.stderr
por um objeto semelhante a arquivo de tradução.Quando o terminal / fluxo ainda não pode codificar todos os caracteres unicode ocorrentes, e quando você não deseja interromper
print
apenas por causa disso, é possível introduzir um comportamento de codificar com substituir no objeto de conversão de arquivo.Aqui está um exemplo:
Usando literais de cadeia simples além do ascii no código Python 2/2 + 3
A única boa razão para alterar a codificação padrão global (apenas para UTF-8) é uma decisão sobre o código-fonte do aplicativo - e não por causa de problemas de codificação de fluxo de E / S: Para escrever literais de cadeia além do ascii no código sem ser forçado para sempre usar
u'string'
escape unicode de estilo. Isso pode ser feito de maneira bastante consistente (apesar do que o artigo de anonbadger diz), cuidando de uma base de código-fonte Python 2 ou Python 2 + 3 que usa consistentemente literais de cadeia simples ascii ou UTF-8 - na medida em que essas cadeias potencialmente sofrem silêncio conversão unicode e mova-se entre módulos ou, potencialmente, vá para stdout. Para isso, prefira "# encoding: utf-8
"ou ascii (sem declaração). Altere ou descarte bibliotecas que ainda dependem de maneira muito idiota fatalmente de erros de codificação padrão ascii além da chr # 127 (que hoje é rara hoje).E faça isso no início do aplicativo (e / ou no site sitecustomize.py), além do
SmartStdout
esquema acima - sem usarreload(sys)
:Dessa maneira, literais de string e a maioria das operações (exceto a iteração de caracteres) funcionam confortavelmente sem pensar na conversão unicode como se houvesse apenas Python3. É claro que as E / S de arquivos sempre precisam de cuidados especiais com relação às codificações - como no Python3.
Nota: as sequências de planícies são convertidas implicitamente de utf-8 em unicode
SmartStdout
antes de serem convertidas no encconding do fluxo de saída.fonte
Aqui está a abordagem que eu usei para produzir código compatível com python2 e python3 e sempre produzi saída utf8 . Encontrei esta resposta em outro lugar, mas não me lembro da fonte.
Essa abordagem funciona substituindo
sys.stdout
por algo que não é muito parecido com arquivo (mas ainda usa apenas coisas na biblioteca padrão). Isso pode causar problemas para suas bibliotecas subjacentes, mas no caso simples em que você tem um bom controle sobre como o sys.stdout out é usado na sua estrutura, essa pode ser uma abordagem razoável.fonte
Isso corrigiu o problema para mim.
fonte
Este é um truque rápido para quem está (1) em uma plataforma Windows (2) executando o Python 2.7 e (3) irritado porque um bom software (ou seja, não foi escrito por você, portanto não é candidato imediato à impressão de codificação / decodificação) manobras) não exibirá os "caracteres unicode bonitos" no ambiente IDLE (Pythonwin imprime muito bem o unicode). Por exemplo, os símbolos lógicos da First Order Logic que Stephan Boyer usa na saída de seu provador pedagógico no First Order Logic Prover .
Eu não gostei da idéia de forçar o recarregamento do sistema e não consegui que o sistema cooperasse com a definição de variáveis de ambiente como PYTHONIOENCODING (tentei a variável de ambiente direta do Windows e também a soltei em sitecustomize.py nos pacotes de sites como um liner = 'utf-8').
Portanto, se você deseja abrir o caminho para o sucesso, vá para o diretório IDLE, normalmente: "C: \ Python27 \ Lib \ idlelib" Localize o arquivo IOBinding.py. Faça uma cópia desse arquivo e armazene-o em outro local para que você possa voltar ao comportamento original quando desejar. Abra o arquivo no idlelib com um editor (por exemplo, IDLE). Vá para esta área de código:
Em outras palavras, comente a linha de código original após a ' tentativa ' que estava tornando a variável de codificação igual a locale.getdefaultlocale (porque isso fornecerá o cp1252 que você não deseja) e, em vez disso, force-a para 'utf-8 '(adicionando a linha' encoding = 'utf-8 ' como mostrado).
Eu acredito que isso afeta apenas a exibição IDLE para stdout e não a codificação usada para nomes de arquivos etc. (que é obtida anteriormente na codificação do sistema de arquivos). Se você tiver algum problema com qualquer outro código executado no IDLE posteriormente, substitua o arquivo IOBinding.py pelo arquivo original não modificado.
fonte
Você pode alterar a codificação de todo o seu sistema operacional. No Ubuntu, você pode fazer isso com
fonte