2010-07-03 13 views
98

Todavía estoy aprendiendo Python y tengo una duda:¿Por qué declarar unicode por cadena en python?

En 2.6.x pitón por lo general declaran codificación en el encabezado del archivo así (como en PEP 0263)

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

Después de eso, mis cuerdas están escritos como de costumbre:

a = "A normal string without declared Unicode" 

Pero cada vez que veo un código de proyecto pitón, la codificación no se declara en la cabecera. En cambio, se declara en cada cadena como esta:

a = u"A string with declared Unicode" 

¿Cuál es la diferencia? ¿Cuál es el propósito de esto? Sé que Python 2.6.x establece la codificación ASCII por defecto, pero puede ser anulada por la declaración del encabezado, entonces, ¿cuál es el punto de la declaración por cadena?

Adición: Parece que he mezclado la codificación de archivos con la codificación de cadenas. Gracias por explicarlo :)

+4

'# codificación: utf8' es lo suficientemente bueno, no hay necesidad de' - * - ' – jellyfish

+0

@jellyfish supongo que quería decir que escribir' # codificación: utf -8'. –

+0

Debe ser '# coding = utf-8'. https://www.python.org/dev/peps/pep-0263/ –

Respuesta

141

Esas son dos cosas diferentes, como otros han mencionado.

Cuando se especifica # -*- coding: utf-8 -*-, usted está diciendo a Python el archivo de origen que ha ahorrado es utf-8. El valor predeterminado para Python 2 es ASCII (para Python 3 es utf-8). Esto solo afecta cómo el intérprete lee los caracteres en el archivo.

En general, probablemente no sea la mejor idea incorporar caracteres de alto Unicode en su archivo sin importar la codificación; puede utilizar cadenas de escape unicode, que funcionan en cualquiera de las codificaciones.


Cuando se declara una cadena con una u delante, como u'This is a string', le dice al compilador de Python que la cadena es Unicode, no bytes. Esto es manejado mayormente de forma transparente por el intérprete; la diferencia más obvia es que ahora puede incrustar caracteres Unicode en la cadena (es decir, u'\u2665' ahora es legal). Puede usar from __future__ import unicode_literals para que sea el predeterminado.

Esto solo se aplica a Python 2; en Python 3, el valor predeterminado es Unicode, y debe especificar un b en el frente (como b'These are bytes', para declarar una secuencia de bytes).

+0

Gracias por la explicación! Estableceré esto como aceptado ya que es el más completo :) –

+2

La codificación fuente predeterminada para Python 2 es ** ascii **. –

+23

En realidad, es una gran idea incorporar caracteres unicode altos en su archivo. Dudo que los que no hablan inglés quieran leer escapes unicode en sus cadenas. –

10

Eso no establece el formato de la cadena; establece el formato del archivo. Incluso con ese encabezado, "hello" es una cadena de bytes, no una cadena Unicode. Para hacerlo Unicode, tendrá que usar u"hello" en todas partes. El encabezado es solo una pista de qué formato usar al leer el archivo .py.

+0

Estaba equivocado entonces, pensé que eran lo mismo. ¿Entonces el uso para cadenas unicode es i18n? –

+0

@Oscar: Sí, en su mayor parte. Si estuviera creando un sitio web con Django o algo así y tuviera que manejar personas con caracteres que no sean ASCII, entonces ese es otro posible uso. – icktoofay

7

La definición del encabezado es definir la codificación del código en sí, no las cadenas resultantes en el tiempo de ejecución.

poniendo un carácter no ASCII como 2 en la secuencia de comandos de Python sin la definición de cabecera UTF-8 lanzará una advertencia error http://www.freeimagehosting.net/uploads/1ed15124c4.jpg

+0

Error incorrecto, pero sí. –

+0

¡Uy, gracias corregidas – ebt

19

Como han dicho otros, # coding: especifica la codificación en la que se guarda el archivo de origen.Aquí están algunos ejemplos para ilustrar esto:

un archivo guardado en el disco como cp437 (mi consola de codificación), pero sin codificación declarada

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

Salida:

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 

Salida del archivo con # coding: cp437 agregado:

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

Al principio, Python desconocía la codificación y se quejaba del carácter no ASCII. Una vez que conocía la codificación, la cadena de bytes obtenía los bytes que estaban realmente en el disco. Para la cadena Unicode, Python leyó \ x81, sabía que en cp437 era ü, y lo decodificó en el punto de código Unicode para ü que es U + 00FC. Cuando se imprimió la cadena de bytes, Python envió el valor hexadecimal 81 directamente a la consola. Cuando se imprimió la cadena Unicode, Python detectó correctamente la codificación de mi consola como cp437 y tradujo Unicode ü en el valor de cp437 para ü.

Esto es lo que ocurre con un archivo declarada y guardado en UTF-8:

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

En UTF-8, ü se codifica como los bytes hexagonal C3 BC, por lo que la cadena de bytes contiene los bytes , pero la cadena Unicode es idéntica al primer ejemplo. Python leyó los dos bytes y lo decodificó correctamente. Python imprimió la cadena de bytes de forma incorrecta, porque envió los dos bytes UTF-8 que representan ü directamente a mi consola cp437.

Aquí el archivo se declara cp437, pero guarda en UTF-8:

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

La cadena de bytes todavía tiene los bytes en el disco (UTF-8 hexagonal bytes C3 BC), sino que los interpreta como dos caracteres cp437 en lugar de un solo carácter codificado en UTF-8. Esos dos caracteres fueron traducidos a puntos de código Unicode y todo se imprime incorrectamente.

+0

+1 para los ejemplos :) –

0

si está utilizando Python 2, añadir lo siguiente: from __future__ import unicode_literals

Cuestiones relacionadas