# 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 - 2020
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