4. Com tratar con los Strings(Cadenas)

4.1 Definiciones

Concepcionalmente una cadena es un lista de caracteres como 'A','B','C' o 'E'. Los caracteres son representaciones abstractas y su significado depende del idioma y contexto en el que se usan. El estandar Unicode describe como los caracteres estan representados por puntos de código. Por ejemplo, los caracteres anteriores se representan con los puntos de código U+0041, U+0042, U+0043, y U+00C9 respectivamente, Básicamente, los puntos Código son numeros en el rango de 0 a 0x10FFFF.

Como se menciono anteriormente, la representacion de una cadena como una lista de puntos de codigo es abstracta. Para convertir esta representacion abstracta en una secuencia de bytes la cadena Unicode debe ser codificada. La forma mas simple de codificacion es ASCII y se realiza de la siguiente manera:

  1. si el punto del codigo es < 128, cada byte es el mismo que el valor del punto de código(code point).
  2. Si el punto de código es 128 o mayor, la cadena Unicode no se puede presentar en esta codificacion.(Python genera una excepción UnicodeEncodeError en este caso.).

Aunque la codificación ASCII es simple de aplicar, sólo puede codificar para 128 caracteres diferentes lo cual es bastante dificil. Una de las codificaciones mas utilizadas para solucionar este problema es UTF-8(Puede manejar cualquier puunto de código Unicode). UTF significa "Unicode Transformation Format", y el '8' significa que se utilizan números de 8 bits en la codificacion.

4.2 Python 2

4.2.1 Soporte Unicode de Python 2.x's

Python 2 viene con dos tipos diferentes de objetos que se pueden utilizar para presentar cadenas, str y unicode . Las instancias de estos ultimos se utilizan para expresar cadenas Unicode, mientras que las str Tipo son representaciones de bytes(la cadena codificada). Bajo el capó, Python representa las cadenas Unicode como enteros de 16 o 32 bits, dependiendo de cómo se complico el Intérprete de Python. Las cadenas Unicode se pueden convertir en cadenas de 8 bits con unicode.encode() :

>>> unicode_string = u"Fu\u00dfb\u00e4lle"
>>> print unicode_string
Fußbälle
>>> type(unicode_string)
<type 'unicode'>
>>> unicode_string.encode("utf-8")
'Fu\xc3\x9fb\xc3\xa4lle'

Las Cadenas de 8 bits de Python tiene un método str.decode () que interpreta la cadena usando la codificacion dada:

>>> utf8_string = unicode_string.encode("utf-8")
>>> type(utf8_string)
<type 'str'>
>>> u2 = utf8_string.decode("utf-8")
>>> unicode_string == u2
True

Por desgracio,python 2.x le permite mezclar unicode y str si la cadena de 8 bits no contiene sólo bytes de 7 bits (ASCII), pero obtendria UnicodeDecodeError si contiene valores no ASCII:

>>> utf8_string = " sind rund"
>>> unicode_string + utf8_string
u'Fu\xdfb\xe4lle sind rund'
>>> utf8_string = " k\xc3\xb6nnten rund sein"
>>> print utf8_string
 könnten rund sein
>>> unicode_string + utf8_string
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2:
ordinal not in range(128)

4.2.2. Unicode en GTK+

GTK+ utiliza cadenas UTF-8 codificadas para todo el texto. Esto significa que si llama a un método que devuelve una cadena siempre obtendrá una instancia del tipo str. Los mismo se aplica a los métodos que esperan una o más cadenas como párametro, deben ser UTF-8 codificado. Sin embargo, por convenencia PyGobject convertira, automáticamente cualquier instancia unicode a str si se suministra como argumento:

>>> from gi.repository import Gtk
>>> label = Gtk.Label()
>>> unicode_string = u"Fu\u00dfb\u00e4lle"
>>> label.set_text(unicode_string)
>>> txt = label.get_text()
>>> type(txt), txt
(<type 'str'>, 'Fu\xc3\x9fb\xc3\xa4lle')
>>> txt == unicode_string
__main__:1: UnicodeWarning: Unicode equal comparison failed to convert
both arguments to Unicode - interpreting them as being unequal
False

Observe la advertencia al final. Aunque llamamos Gtk.Label.set_text() con una instancia unicode como argumento, Gtk.Label.get_text() siempre devolverá una instancia str. Por consiguiente, txt y unicode_string no son iguales.

Esto es especialmente importante si desea internacionalizar su programa utilizando gettext. Debe asegurarse de que gettext devolverá cadenas de8 bits codificadas en UTF-8 para todos los idiomas. En general , se recomienda no usar objetos unicode en aplicaciones GTK+ en absoluto y solo usar objetos codificados UTF-8 codificados, ya que GTK+ no se integran complentamente con objetos unicode. De lo contrario, tendria que decoficar los valores de retorno a cadenas Unicode cada vez que llama a un metodo GTK+:

>>> txt = label.get_text().decode("utf-8")
>>> txt == unicode_string
True

4.3. Python 3

4.3.1. Soporte Unico de Python 3.x's

Desde Python 3.0, todas las cadenas se almacenan como Unicode en una instancia del tipo str. Las cadenas codificadas por otro lado se representan como datos binarios en forma de instancias del tipo de bytes. Conceptualmente, str se refiere al texto, mientras que los bytes se refieren a los datos. Utilice str.encode()para ir de str a bytes y bytes.decode() para ir de bytes a str.

Además, ya no es posible mezclar cadenas Unicode con cadenas codificadas, ya que resultará en un TypeError:

>>> text = "Fu\u00dfb\u00e4lle"
>>> data = b" sind rund"
>>> text + data
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'bytes' object to str implicitly
>>> text + data.decode("utf-8")
'Fußbälle sind rund'
>>> text.encode("utf-8") + data
b'Fu\xc3\x9fb\xc3\xa4lle sind rund'

4.3.2. Unicode en GTK+

Como consecuencia, las cosas son mucho mas limpias y consistentes con Python 3.x, porque PyGobjet codificará / descoficará automaticamente a /desde UTF-8 si pasa una cadena a un metodo o un metodo devuelve una cadena. Las cadenas, o texto, siempre se representarán como instancias de strsolamente:

>>> from gi.repository import Gtk
>>> label = Gtk.Label()
>>> text = "Fu\u00dfb\u00e4lle"
>>> label.set_text(text)
>>> txt = label.get_text()
>>> type(txt), txt
(<class 'str'>, 'Fußbälle')
>>> txt == text
True

4.4. Referencias

Lo nuevo de python 3.0 describe los nuevos conceptos que distinguen claramente entre texto y datos.

El Unicode HOWTO discute la compatibilidad de Python 2.x con Unicode y explica varios problemas que comunmente encuentran las personas cuando tratan de trabajar con Unicode.

El unicode HOWTO para Python 3.x discute soporte Unicode en Python 3.x.

Tabla de codificacion UTF-8 y caracteres Unicode contiene una lista de puntos de código Unicode y su conficacion UTF-8 respectiva.

results matching ""

    No results matching ""