[Python-es] Sobre los unicodes

Chema Cortes chemacortes en wanadoo.es
Vie Jul 5 10:52:45 CEST 2002


Hola a todos:

Ya que parece que hay cierta confusión con los unicodes, voy a intentar explicar un poco el tema:

La codificación "unicode" pretende unificar los distintos sistemas de codificación en uno sólo. El problema es que en la práctica seguimos atados a la codificación que haga el sistema operativo con el que estemos trabajando, del que dependemos para las entradas y salidas de información.

Por ello, cuando definimos una cadena unicode solemos hacerlo partiendo de otro sistema de codificación:

s=unicode("España","latin1")

El sistema de codificación por defecto de los unicodes (el del sistema operativo) se obtiene de 'sys.getdefaultencoding'. Podemos cambiarlo mediante 'sys.setdefaultencoding', algo que suele estar impedido a propósito para que sólo se pueda cambiar desde el fichero 'site.py' (mirar el tratamiento de la variable 'encoding' en 'site.py').

Como se puede ver en 'site.py', el sistema de codificación por defecto suele ser el "ascii" (ASCII de 7 bits) por ser el más estándar. Como no suele ser suficiente, para los idiomas europeos occidentales se emplea una extensión de la tabla ascii, de 8 bits, conocida por "latin1" ó "iso8859-1". Con el Euro, esta codificación ha sido modificada para añadir el símbolo del Euro y el cent pasando a ser "latin0" ó "iso8859-15". Una de las características a tener en cuenta es que los 256 primeros caracteres del unicode coinciden exactamente con los de la codificación "latin1", por lo que se puede hablar de una conversión directa de latin1 a unicode. Y tanto es así que cuando expresamos una cadena unicode por u'..' estamos implícitamente codificando desde latin1, independiente de cómo sea el sistema de codificación por defecto. O sea:

s=u'España'

equivale a

s=unicode("España","latin1")

Esto es importante, ya que si por ejemplo en windows (que usa la codificación "mbcs") hacemos:

>>> s=u'€'
>>> s
u'\x80'

Vemos que nos codifica mal la cadena. La manera adecuada es:

>>> s=unicode('€',"mbcs")
>>> s
u'\u20ac'

y esto aunque tengamos puesto por defecto la codificación "mbcs".

De todos modos, es conviene que, para los que usamos otro idioma que no sea el inglés, la codificación por defecto corresponda con la del sistema operativo ("latin1" en linux, "mbcs" en windows, "macroman" en mac). Para ello bastará con cambiar la variable 'encoding' del fichero 'site.py' por la de la codificación correspondiente. 

Para aclarar (o para liar más) la cosa, veamos un ejemplo en linux:

>>> s=u'\N{EURO SIGN}'
>>> s
u'\u20ac'
>>> ord(s)
8364
>>> print s
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeError: ASCII encoding error: ordinal not in range(128)
>>> print s.encode("latin1")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeError: Latin-1 encoding error: ordinal not in range(256)
>>> print s.encode("iso8859-15")
€
>>>

Aquí hemos definido una cadena unicode a partir del nombre del símbolo, el Euro, que está fuera del rango de los 256 caracteres del latin1. Como se ve, da error cuando intenta codificar en ascii (implícitamente) y cuando queremos codificar en latin1 (explícitamente). Tenemos que pasar a latin0 (iso8859-15) para conseguir que se imprima el símbolo correctamente en la cónsola.


NOTA1: el ejemplo lo he probado en linux con LANG='es_ES en euro'

NOTA2: hay 4 formas de escape para definir una cadena unicode

2 dígitos hex   u'\xb0'
4 dígitos hex   u'\u00b0'
8 dígitos hex   u'\U000000b0'
por nombre      u'\N{DEGREE SIGN}'

Los nombres se pueden obtener con el módulo 'unicodedata'


Espero haber dado algo de luz a lío con los unicode. Si hace falta alguna corrección, agradecería que me lo indicarais para dejar el texto corregido como "guía al unicode".

Saludos,
Chema Cortés <chemacortes en wanadoo.es
_____________________________________________________________________
No olvides nada. Recuerda los cumpleaños, tus citas, tus cenas románticas y 
todo lo que quieras usando la Agenda personal de Wanadoo.es, desde cualquier 
lugar conectado a Internet. Visítala en http://www.wanadoo.es/agenda






Más información sobre la lista de distribución Python-es