Les chaînes de caractères
Aussi disponible en mode diaporama…
VuesConstruction de chaînes de caractères
Commençons avec une liste de chaînes de caractères :
colors = ['red', 'blue', 'green', 'yellow']
On veut concaténer ces chaînes ensemble pour en créer une longue. Particulièrement lorsque le nombre de sous-chaînes est gros...
Ne faites pas :
result = ''
for s in colors:
result += s
C'est très lent. Ça utilise énormément de mémoire et de performances. La somme va additionner, stocker, et ensuite passer à la suite pour chaque étape intermédiaire.
Faites plutôt ceci :
result = ''.join(colors)
La méthode join() fait toute la copie en une seule passe.
Lorsque vous ne traitez qu'une petite centaine de chaînes de caractères, ça ne fait aucune différence. Mais prenez l'habitude de construire vos chaînes de façon optimale, car avec des milliers ou des boucles, ça va faire la différence.
Construire des chaînes, solutions 1
Voici quelques techniques pour utiliser la méthode join().
Si vous voulez un espace comme séparateur :
result = ' '.join(colors)
ou une virgule et un espace :
result = ', '.join(colors)
voici un cas courant d'utilisation :
colors = ['red', 'blue', 'green', 'yellow']
print 'Choose', ', '.join(colors[:-1]), \
'or', colors[-1]
Pour faire une phrase grammaticalement correcte, on veut des virgules entre
chaque valeurs sauf la dernière, où l'on préfère un "ou". La syntaxe de
découpage d'une liste s'occupe du reste. La "partie jusqu'à -1" ([:-1])
retourne tout sauf la dernière valeur, que l'on peut concaténer avec nos
virgules.
Bien sûr, ce code ne fonctionnera pas avec les cas particuliers comme une liste de taille 0 ou 1. Ce qui retourne :
Choose red, blue, green or yellow
Construire des chaînes, solutions 2
Vous avez besoin d'appliquer une fonction pour générer les chaînes initiales :
result = ''.join(fn(i) for i in items)
Ça utilise une generator expression, dont on parlera plus tard.
Si vous devez modifier les chaînes de manière incrémentale, commencez par les stocker dans une liste pour commencer :
items = []
...
items.append(item) # de nombreuses fois
...
# une fois la liste complétée
result = ''.join(fn(i) for i in items)
On accumule les parties de la liste afin de pouvoir appliquer le join,
ce qui est plus rapide.
Formattage des chaînes de caractères avec %
L'opérateur % fonctionne en Python comme la fonction sprintf de C.
Bien sûr si vous ne connaissez pas C, ça ne vous aide pas. Pour faire simple, vous définissez un template ou format et des valeurs qui seront interprétées.
Dans cet exemple, le template contient deux spécifications de conversion
"%s" signifie "insérer une chaîne de caractère ici" et "%i" signifie
"convertir un integer en string et l'insérer ici". "%s" est particulièrement
utile car il utilise la fonction standard str() pour convertir un objet
en une chaîne de caractères.
Les valeurs proposées doivent correspondrent au template, on a deux valeurs ici, un tuple.
name = 'David'
messages = 3
text = ('Hello %s, you have %i messages'
% (name, messages))
print text
Ce qui donne :
Hello David, you have 3 messages
Les détails sont dans la Python Library Reference, section 2.3.6.2, "String Formatting Operations". Mettez cette page en favoris !
Si vous ne l'avez pas encore fait, allez sur python.org, téléchargez la documentation en HTML (dans un .zip ou une archive), et installez la sur votre machine. Il n'y a rien de mieux que d'avoir la ressource de référence à portée de clavier.
Formattage des chaînes de caractères avancé
Pourquoi est-ce qu'il y a autant de personnes qui ne réalisent pas qu'il y a d'autres façons de formater les chaînes de caractères qui peuvent s'avérer plus puissantes ?
Avec des noms grâce à un dictionnaire :
values = {'name': name, 'messages': messages}
print ('Hello %(name)s, you have %(messages)i '
'messages' % values)
Ici on a spécifié les noms des valeurs interprétées, qui constituent les clés du dictionnaire.
Vous trouvez qu'il y a de la redondance ? Les noms "name" et "messages" sont déjà définis localement. On peut en tirer parti.
En utilisant les variables locales :
print ('Hello %(name)s, you have %(messages)i '
'messages' % locals())
La fonction locals() retourne un dictionnaire de toutes les variables
locales disponibles.
C'est très puissant. Grâce à ça, vous pouvez formater toutes les chaînes de caractères que vous voulez sans avoir à vous soucier de la correspondance positionnelle avec les valeurs soumises en argument.
Mais le pouvoir peut être dangereux. ("With great power comes great
responsibility.") Si vous utilisez locals() avec un template issu d'une
ressource externe, vous exposez l'intégralité de votre espace de noms local.
C'est une chose à garder en tête.
Pour examiner votre espace de nom local :
>>> from pprint import pprint
>>> pprint(locals())
pprint est un module très utile. Si vous ne le connaissiez pas déjà,
essayez de jouer avec. Ça rend le debugging des données structurées beaucoup
plus simple !
Formattage des chaînes de caractères avancé
L'espace de nom des attributs d'une instance d'objet est simplement un
dictionnaire, self.__dict__.
En utilisant l'espace de nom d'une instance :
print ("We found %(error_count)d errors"
% self.__dict__)
Equivalent à, mais moins flexible que :
print ("We found %d errors"
% self.error_count)
Note: Les attributs d'une classe sont dans le __dict__ de la classe.
Les espaces de noms sont hérités et constituent donc des dictionnaires
chaînés.

