Cadenas (Python) Una explicación de cómo trabajar con cadenas en Python y GTK+. Sebastian Pölsterl sebp@k-d-w.org 2011 Marta Maria Casetti mmcasetti@gmail.com 2012 Daniel Mustieles daniel.mustieles@gmail.com 2011 - 2017 Nicolás Satragno nsatragno@gmail.com 2012 - 2013 Jorge González jorgegonz@svn.gnome.org 2011 Cadenas

GNOME recomienda fuertemente el uso de Python 3 para escribir aplicaciones.

Cadenas en Python 2

Python 2 viene con dos tipos de objetos diferentes que pueden usarse para representar cadenas, str y unicode. Las instancias de unicode se usan para expresar cadenas de Unicode, mientras que las instancias del tipo str son representaciones de bytes (la cadena codificada). A nivel funcional, Python representa las cadenas de Unicode como enteros de 16 ó 32 bits, dependiendo de cómo se compiló su intérprete.

>>> unicode_string = u"Fu\u00dfb\u00e4lle" >>> print unicode_string Fußbälle

Las cadenas de Unicode pueden convertirse a cadenas de 8 bits con unicode.encode(). Las cadenas de 8 bits de Python tienen un método str.decode() que interpreta la cadena usando la codificación dada (es decir, es la inversa de unicode.encode()):

>>> type(unicode_string) <type 'unicode'> >>> unicode_string.encode("utf-8") 'Fu\xc3\x9fb\xc3\xa4lle' >>> utf8_string = unicode_string.encode("utf-8") >>> type(utf8_string) <type 'str'> >>> unicode_string == utf8_string.decode("utf-8") True

Desafortunadamente, Python 2.x le permite mezclar unicode y str si la cadena de 8 bits contuviera sólo bytes de 7 bits (ASCII), pero obtendría UnicodeDecodeError si contuviera valores no ASCII.

Cadenas en Python 3

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 la forma de instancias del tipo de bytes. Conceptualmente, str se refiere a texto, mientras que bytes se refieren a datos. Use encode() para ir de str a bytes, y decode() para ir de bytes a str.

Además, ya no es posible mezclar cadenas de Unicode con cadenas codificadas, porque se producirá 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'
Unicode en GTK+

GTK+ usa cadenas codificadas con UTF-8 para todo el texto. Esto significa que si llama a un método que devuelve una cadena, siempre obtendrá una instancia del tipo str. Lo mismo se aplica a métodos que esperan una o más cadenas como parámetro, deben estar codificadas con UTF-8. Sin embargo, por comodidad, PyGObject convertirá automáticamente cualquier instancia de Unicode a «str» si se proporciona 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) <type 'str'>

Además:

>>> txt == unicode_string

devolvería False, con la advertencia __main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal (Gtk.Label.get_text() devolverá siempre una instancia de str; por lo tanto, txt y unicode_string no son iguales).

Esto es especialmente importante si quiere internacionalizar su programa usando gettext. Tiene que asegurarse de que gettext devuelva cadenas de 8 bits codificadas con UTF-8 para todos los idiomas.

En general se recomienda no usar ningún objeto de unicode en aplicaciones de GTK+, y sólo usar objetos str codificados con UTF-8 dado que GTK+ no integra completamente objetos unicode.

En Python 3.x las codificación de cadenas es más consistente, porque PyGObject automáticamente codifica/decodifica hacia/desde UTF-8 si le pasa una cadena a un método o un método devuelve una cadena. Las cadenas, o el texto, siempre se representarán sólo como instancias de str.

Referencias

Cómo manejar cadenas: el tutorial de GTK+ 3 en Python