Cómo usar y aprovechar el soporte de Unicode que Python trae de serie. Si no tienes muy claro de que va esto del Unicode, te recomiendo leer primero la receta Unicode y UTF-8.

Introducción

Python tiene soporte nativo para Unicode y sus encodings más populares. Si ejecutas un interprete de Python en un terminal, lo habitual es que herede el encoding por defecto. Para esta receta se supone que tus “locales” son es_ES.UTF-8. Puedes comprobarlo con:

>>> import sys
>>> sys.stdin.encoding
'UTF-8'

Crear cadenas Unicode

Cualquier cadena Unicode debe estar expresada con un encoding concreto. Python intentará utilizar siempre su encoding por defecto, que se puede obtener con:

>>> sys.getdefaultencoding()
'ascii'

Para indicar que una cadena es Unicode basta con escribir el caracter ‘u’ delante de la cadena, o bien construir un objeto de tipo unicode():

>>> u'hola'
u'hola'
>>> unicode('hola')
u'hola'

Como verás, al indicar una variable o literal, el interprete muestra la representación interna de esa variable.

Si sólo utilizas caracteres ‘ascii’, la representación interna es igual, como en el ejemplo anterior. Pero si utilizas caracteres no-ascii, la cosa cambia:

>>> u'año'
u'a\xf1o'
>>> unicode('año')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

En la primera sentencia del ejemplo de arriba, Python entiende que la cadena está escrita con el codec del terminal (utf-8) porque se está dando como un literal; pero en el segundo caso el interprete entiende (por defecto) que el string es ‘ascii’, lo cual es un error, puesto que ‘ascii’ no puede representar el carácter unicode ‘ñ’. Por tanto, si la cadena está expresada en un codec diferente, es necesario indicarlo explícitamente:

>>> unicode('año', 'utf-8')
u'a\xf1o'

Insertar caracteres ‘raros’

Los literales unicode pueden contener caracteres expresados por su número. Por ejemplo:

>>> cad = u'hola\u2605'
>>> cad
u'hola\u2605'
>>> print cad  
hola★

En la última línea del ejemplo deberías ver un estrella negra de 5 puntas, pero eso depende de la calidad de tu navegador (usa firefox, o iceweasel si estás en Debian).

Como es dificil recordar secuencias de números, Python permite especificar un carácter por su nombre. El equivalente de la asignación anterior es:

>>> cad = u'hola\N{BLACK STAR}' 

El módulo unicodedata tiene funciones específicas para las tareas de identificación y nombrado de caracteres unicode.

También tienes una función estándar (unichr()) para convertir un código unicode a carácter:

>>> cad = unichr(0x1d160)

Aplicar una codificación (encode)

A partir de una cadena Unicode se puede obtener su representación con diferentes codecs usando el método encode().

>>> cad = u’año’
>>> cad
u’a\xf1o’
>>> print cad
año
>>> cad.encode(‘utf-8’)
‘a\xc3\xb1o’
>>> cad.encode(‘utf-16’)
‘\xff\xfea\x00\xf1\x00o\x00'

Si el codec indicado no puede codificar la cadena unicode indicada, hay varias alternativas, dependiendo del 2º argumento del método encode()

>>> cad.encode(‘ascii’, ‘strict’) # es el modo por defecto
UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\xf1’ in position 1: ordinal not in range(128)
>>> cad.encode(‘ascii’, ‘ignore’)
‘ao’
>>> cad.encode(‘ascii’, ‘replace’)
‘a?o’

Leer cadenas de un fichero (decode)

[Por hacer]

El módulo codecs

[Por hacer]

Referencias



blog comments powered by Disqus