it-swarm.dev

Por que declarar unicode por string em python?

Eu ainda estou aprendendo python e tenho uma dúvida:

Em python 2.6.x eu geralmente declaro codificação no cabeçalho do arquivo como este (como em PEP 026 )

# -*- coding: utf-8 -*-

Depois disso, minhas cordas são escritas como de costume:

a = "A normal string without declared Unicode"

Mas toda vez que vejo um código de projeto python, a codificação não é declarada no cabeçalho. Em vez disso, é declarado em todas as cadeias da seguinte forma:

a = u"A string with declared Unicode"

Qual é a diferença? Qual é o propósito disso? Eu sei Python 2.6.x sets ASCII codificando por padrão, mas ele pode ser substituído pela declaração de cabeçalho, então qual é o ponto de declaração por string?

Adendo: Parece que eu misturei a codificação de arquivos com a codificação de string. Obrigado por explicar :)

115
Oscar Carballal

Essas são duas coisas diferentes, como outras pessoas mencionaram.

Quando você especifica # -*- coding: utf-8 -*-, você está dizendo Python o arquivo de origem que você salvou é utf-8. O padrão para Python 2 é ASCII (para Python 3 é utf-8). Isso afeta apenas como o interpretador lê os caracteres no arquivo.

Em geral, provavelmente não é a melhor idéia incorporar caracteres unicode ao seu arquivo, não importa qual seja a codificação; você pode usar escapes unicode de string, que funcionam na codificação.


Quando você declara uma string com um u na frente, como u'This is a string', ela diz ao compilador Pythonque 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 (isto é, u'\u2665' agora é legal). Você pode usar from __future__ import unicode_literals para torná-lo o padrão.

Isso só se aplica a Python 2; em Python 3 o padrão é Unicode, e você precisa especificar um b na frente (como b'These are bytes', para declarar uma seqüência de bytes).

157
Chris B.

Como outros já disseram, # coding: especifica a codificação em que o arquivo de origem é salvo. Aqui estão alguns exemplos para ilustrar isso:

m arquivo salvo em disco como cp437 (minha codificação de console), mas nenhuma codificação declarada

b = 'über'
u = u'über'
print b,repr(b)
print u,repr(u)

saída:

  File "C:\ex.py", line 1
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details

Saída do arquivo com # coding: cp437 adicionado:

über '\x81ber'
über u'\xfcber'

Primeiramente, o Python não conhecia a codificação e reclamava do caracter não-ASCII. Assim que soube da codificação, a cadeia de bytes obteve os bytes que estavam no disco. Para a cadeia Unicode, Python read\x81, sabia que em cp437 era ( =, e decodificou-o no ponto de código Unicode para ü que é U + 00FC. Quando a cadeia de bytes foi impressa, Python enviou o valor hexadecimal 81 para o console diretamente. Quando a cadeia Unicode foi impressa, Python detectou corretamente minha codificação de console como cp437 e traduziu Unicode ü para o valor cp437 para ü.

Aqui está o que acontece com um arquivo declarado e salvo em UTF-8:

├╝ber '\xc3\xbcber'
über u'\xfcber'

Em UTF-8, ü é codificado como bytes hexadecimais C3 BC, portanto, a cadeia de bytes contém esses bytes, mas a cadeia Unicode é idêntica ao primeiro exemplo. Python leu os dois bytes e os decodificou corretamente. Python imprimiu a string de byte incorretamente, porque ela enviou os dois bytes UTF-8 representando ü diretamente para o meu console cp437.

Aqui o arquivo é declarado cp437, mas salvo em UTF-8:

├╝ber '\xc3\xbcber'
├╝ber u'\u251c\u255dber'

A cadeia de bytes ainda tem os bytes no disco (bytes hexadecimais UTF-8 C3 BC), mas os interpreta como dois caracteres cp437 em vez de um único caractere codificado em UTF-8. Esses dois caracteres são convertidos para pontos de código Unicode e tudo é impresso incorretamente.

22
Mark Tolonen

Isso não define o formato da string; define o formato do arquivo. Mesmo com esse cabeçalho, "hello" é uma string de byte, não uma string Unicode. Para torná-lo Unicode, você terá que usar u"hello" em todos os lugares. O cabeçalho é apenas uma sugestão de qual formato usar ao ler o arquivo .py.

10
icktoofay

A definição do cabeçalho é definir a codificação do próprio código, não as sequências resultantes no tempo de execução.

colocar um caractere não ascii como ۲ no script python sem a definição do cabeçalho utf-8 lançará um aviso erro http://www.freeimagehosting.net/uploads/1ed15124c4.jpg

7
ebt