GNOME recomienda fuertemente el uso de Python 3 para escribir aplicaciones.
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
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'
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
.
Cómo manejar cadenas: el tutorial de GTK+ 3 en Python