Ainda estou aprendendo python e tenho uma dúvida:
No python 2.6.x, normalmente declaro codificação no cabeçalho do arquivo como este (como no PEP 0263 )
# -*- coding: utf-8 -*-
Depois disso, minhas cordas são escritas como de costume:
a = "A normal string without declared Unicode"
Mas sempre que vejo um código de projeto python, a codificação não é declarada no cabeçalho. Em vez disso, é declarado em cada sequência como esta:
a = u"A string with declared Unicode"
Qual é a diferença? Qual é o objetivo disso? Eu sei que o Python 2.6.x define a codificação ASCII por padrão, mas pode ser substituída pela declaração do cabeçalho, então qual é o ponto da declaração por string?
Adendo: Parece que eu misturei codificação de arquivo com codificação de string. Obrigado por explicar :)
# coding: utf8
é bom o suficiente, não há necessidade de-*-
# coding: utf-8
.#coding=utf-8
. python.org/dev/peps/pep-0263Respostas:
Essas são duas coisas diferentes, como outros já mencionaram.
Ao especificar
# -*- coding: utf-8 -*-
, você está dizendo ao Python o arquivo de origem que você salvouutf-8
. O padrão para o Python 2 é ASCII (para o Python 3 éutf-8
). Isso afeta apenas como o intérprete lê os caracteres no arquivo.Em geral, provavelmente não é a melhor ideia incorporar caracteres unicode altos em seu arquivo, independentemente da codificação; você pode usar escapes unicode de string, que funcionam em qualquer uma das codificações.
Quando você declara uma string com um
u
na frente , comou'This is a string'
, ele diz ao compilador Python que a string é Unicode, não bytes. Isso é tratado principalmente de forma transparente pelo intérprete; a diferença mais óbvia é que agora você pode incorporar caracteres unicode na string (ou seja,u'\u2665'
agora é legal). Você pode usarfrom __future__ import unicode_literals
para torná-lo o padrão.Isso se aplica apenas ao Python 2; no Python 3, o padrão é Unicode e você precisa especificar um
b
na frente (comob'These are bytes'
, para declarar uma sequência de bytes).fonte
Como já foi dito,
# coding:
especifica a codificação na qual o arquivo de origem é salvo. Aqui estão alguns exemplos para ilustrar isso:Um arquivo salvo no disco como cp437 (codificação do meu console), mas nenhuma codificação declarada
Resultado:
Saída do arquivo com
# coding: cp437
adição:No começo, o Python não conhecia a codificação e reclamou do caractere não ASCII. Depois de conhecer a codificação, a sequência de bytes obteve os bytes que estavam no disco. Para a cadeia Unicode, o Python leu \ x81, sabia que no cp437 era um ü e o decodificou no ponto de código Unicode para ü, que é U + 00FC. Quando a sequência de bytes foi impressa, o Python enviou o valor hexadecimal
81
ao console diretamente. Quando a string Unicode foi impressa, o Python detectou corretamente a codificação do console como cp437 e converteu Unicode ü no valor cp437 de ü .Aqui está o que acontece com um arquivo declarado e salvo em UTF-8:
No UTF-8, ü é codificado como bytes hexadecimais
C3 BC
, portanto a sequência de bytes contém esses bytes, mas a sequência Unicode é idêntica ao primeiro exemplo. O Python leu os dois bytes e decodificou-o corretamente. O Python imprimiu a sequência de bytes incorretamente, porque enviou os dois bytes UTF-8 que representam ü diretamente ao meu console do cp437.Aqui, o arquivo é declarado cp437, mas salvo em UTF-8:
A sequência de bytes ainda obteve os bytes no disco (bytes hexadecimais UTF-8
C3 BC
), mas os interpretou como dois caracteres cp437 em vez de um único caractere codificado em UTF-8. Esses dois caracteres foram traduzidos para pontos de código Unicode e tudo é impresso incorretamente.fonte
Isso não define o formato da string; define o formato do arquivo. Mesmo com esse cabeçalho,
"hello"
é uma sequência de bytes, não uma sequência Unicode. Para torná-lo Unicode, você precisará usar emu"hello"
qualquer lugar. O cabeçalho é apenas uma dica de qual formato usar ao ler o.py
arquivo.fonte
A definição do cabeçalho é definir a codificação do próprio código, não as seqüências resultantes no tempo de execução.
colocar um caractere não-ascii como ۲ no script python sem a definição de cabeçalho utf-8 emitirá um aviso
fonte
Eu criei o seguinte módulo chamado unicoder para poder fazer a transformação em variáveis:
Em seu programa, você pode fazer o seguinte:
fonte