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

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 "<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 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) <type 'str'>

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