Strings (Python) Une explication sur l'utilisation des chaînes de caractères dans Python et GTK+. Sebastian Pölsterl sebp@k-d-w.org 2011 Marta Maria Casetti mmcasetti@gmail.com 2012 Luc Rebert, traduc@rebert.name 2011 Alain Lojewski, allomervan@gmail.com 2011-2012 Luc Pionchon pionchon.luc@gmail.com 2011 Bruno Brouard annoa.b@gmail.com 2011-12 Luis Menina liberforce@freeside.fr 2014 Chaînes de caractères

GNOME strongly encourages the use of Python 3 for writing applications!

Les chaînes de caractères dans Python 2

Python 2 est livré avec deux types différents d'objets qui peuvent être utilisés pour représenter des chaînes : str et unicode. Les instances du type unicode sont utilisées pour exprimer des chaînes Unicode, alors que les exemples du type str sont des représentations d'octets (la chaîne codée). En interne, Python représente les chaînes Unicode par des entiers de 16 ou de 32 bits, en fonction du type de compilation de l'interpréteur Python.

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

Les chaînes Unicode peuvent être converties en 8 bits avec unicode.encode(). Les chaînes Python en 8 bits contiennent une méthode str.decode() qui interprète la chaîne avec le codage qui lui est attribué (c'est donc l'inverse de unicode.encode()) :

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

Malheureusement, Python 2.x vous permet de mélanger les types unicode et str s'il arrivait que la chaîne de 8 bits ne contienne que des octets de 7 bits (ASCII), mais retourne l'erreur UnicodeDecodeError si elle contient des valeurs qui ne sont pas ASCII.

Les chaînes dans Python 3

Since Python 3.0, all strings are stored as Unicode in an instance of the str type. Encoded strings on the other hand are represented as binary data in the form of instances of the bytes type. Conceptually, str refers to text, whereas bytes refers to data. Use encode() to go from str to bytes, and decode() to go from bytes to str.

En plus, il n'est plus possible de mélanger des chaînes Unicode avec des chaînes codées, car cela retournerait une erreur TypeError :

>> text = "Fu\u00dfb\u00e4lle" >>> data = b" sind rund" >>> text + data Traceback (most recent call last): File "", line 1, in 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 dans GTK+

GTK+ utilise des chaînes au format UTF-8 pour tout ce qui est texte. Cela signifie que, si vous appelez une méthode qui renvoie une chaîne, vous obtenez toujours une représentation du type str. Cela s'applique également aux méthodes qui considèrent une ou plusieurs chaînes comme paramètres, elles doivent aussi être codées en UTF-8. Cependant, pour plus de souplesse, PyGObject convertit automatiquement n'importe quelle représentation Unicode au format str si vous lui donnez comme argument :

>> 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) ]]>

Furthermore:

>> txt == unicode_string]]>

devrait renvoyer False, avec l'avertissement __main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal (Gtk.Label.get_text() renvoie toujours une représentation str ; en conséquence, txt et unicode_string sont inégaux).

Cela est particulièrement important si vous voulez internationnaliser votre programme avec gettext. Vous devez vous assurer que gettext va renvoyer des chaînes codées en UTF-8 pour toutes les langues.

D'une manière générale, nous vous recommandons de ne pas du tout utiliser d'objets unicode dans les applications GTK+, mais seulement des objets str codés en UTF-8, car GTK+ n'intègre pas tous les objets unicode.

String encoding is more consistent in Python 3.x because PyGObject will automatically encode/decode to/from UTF-8 if you pass a string to a method or a method returns a string. Strings, or text, will always be represented as instances of str only.

Références

How To Deal With Strings - The Python GTK+ 3 Tutorial