Image de l'article

Le formatage des chaînes de caractères avec Python

Il existe plusieurs façons de formater une chaîne de caractères. Depuis la version 3.6 de Python, une des façons de faire les plus efficaces est d'utiliser les f-string.

Publié le 08 juillet 2020 par ThibH

Le terme de « formatage » de chaînes n'a rien à voir avec le formatage d'un disque dur.

Par « formatage », on entend « mise en forme » et il existe de nombreuses façons de mettre en forme des chaînes de caractères avec Python.

Dans cet article, nous allons donc passer en revue différentes façons de « formater » des chaînes de caractères.

Au commencement, il y avait la concaténation

Avant de parler de formatage, on parle souvent de concaténation.

La concaténation consiste à mettre bout à bout plusieurs chaînes de caractères.

La concaténation peut se faire très simplement avec l'opérateur mathématique + :

protocole = "https://"
nom_du_site = "Docstring"
extension = "fr"

url = protocole + "www." + nom_du_site + "." + extension

Ça fonctionne, mais très rapidement vous allez observer deux problèmes :

  • Ce n'est pas très agréable à lire.
  • Vous ne pouvez concaténer que des objets du même type (car Python est un langage fortement typé).

Ainsi, le code suivant retournera une erreur car la variable age est un nombre entier :

>>> age = 26
>>> phrase = "J'ai " + age + " ans."
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not int

Pour palier à cette erreur, il faut convertir la variable age en chaîne de caractères :

>>> age = 26
>>> phrase = "J'ai " + str(age) + " ans."
"J'ai 26 ans."

Et on retombe sur le premier problème : ça devient très vite difficile à lire et c'est le meilleur moyen de se retrouver avec des TypeError.

Il existe un autre moyen d'insérer des objets dans une chaîne de caractères qui permet de spécifier directement le type des données insérées.

Cette façon de faire est obsolète mais on continue de la retrouver dans de nombreux scripts Python. Il est important de comprendre donc de quoi il en retourne.

Pour ce faire, on utilise l'opérateur modulo (%) et on spécifie ensuite le format des données que l'on insère dans la chaîne de caractères.

age = 26
phrase = "J'ai %d ans." %age  # "J'ai 26 ans."
phrase = "J'ai %f ans." %age  # "J'ai 26.000000 ans."

👉 En utilisant %d on se retrouve avec un nombre entier.

👉 En utilisant %f, la variable age, qui est au départ un nombre entier, se retrouve dans la chaîne de caractères sous forme de nombre décimal :

Cette façon de faire a été longtemps la méthode privilégiée pour formater des chaînes de caractères, raison pour laquelle vous la verrez souvent dans certains scripts.

Certains continuent même d'utiliser cette façon de faire alors qu'il existe maintenant des méthodes bien plus efficaces comme celles que nous allons voir dans la suite de cet article.

La méthode format

Pour éviter les erreurs de type et insérer des objets dans une chaîne de caractères, on peut utiliser la méthode format.

Cette méthode permet d'insérer des objets à l'intérieur d'emplacements spécifiés dans la chaîne de caractères par des accolades :

age = 26
phrase = "J'ai {} ans".format(age)

Ici, pas besoin de convertir la variable age en chaîne de caractères. La méthode format s'en charge pour nous et nous évitons ainsi le TypeError.

Cela permet également de garder une certaine continuité dans notre chaîne de caractères qui ne se retrouve pas entrecoupée d'opérateurs +.

On peut également spécifier à l'intérieur des accolades un nom qu'on utilisera comme paramètre dans la méthode format pour obtenir une phrase encore plus claire :

age_de_lutilisateur = 26
phrase = "J'ai {age} ans".format(age=age_de_lutilisateur)

On peut mettre autant d'emplacements dans une chaîne de caractères que nécessaire.

Il faudra cependant faire attention de passer autant d'éléments à la méthode format qu'il y a d'emplacements dans notre chaîne de caractères.

Par exemple, le code suivant fonctionne :

prenom = "Pierre"
age = 26
phrase = "Je m'appelle {} et j'ai {} ans.".format(prenom, age)

Mais ci-dessous nous aurons une erreur (IndexError: tuple index out of range) car il y a deux emplacements dans la chaîne de caractères mais un seul élément est passé à la méthode format :

prenom = "Pierre"
age = 26
phrase = "Je m'appelle {} et j'ai {} ans.".format(prenom)

On peut également spécifier à l'intérieur des accolades un indice, qui fera référence à la position de l'argument de la méthode format à utiliser.

👉 C'est très pratique si vous souhaitez réutiliser un argument :

prenom = "Pierre"
age = 26
langage = "Python"
phrase = "Je m'appelle {0} et j'ai {1} ans. {0} apprends le langage {2}.".format(prenom, age, langage)
# Je m'appelle Pierre et j'ai 26 ans. Pierre apprends le langage Python.

On peut également remettre des noms à l'intérieur des accolades afin d'obtenir quelque chose de plus agréable à lire :

prenom = "Pierre"
age = 26
langage = "Python"
phrase = "Je m'appelle {prenom} et j'ai {age} ans. {prenom} apprends le langage {langage}.".format(prenom=prenom,
                                                                                                   age=age,
                                                                                                   langage=langage)
Le nom que vous mettez à l'intérieur des accolades n'a pas besoin d'être le même que la variable que vous passez à la méthode format. On aurait très bien pu faire :
prenom = "Pierre"
age = 26
langage = "Python"
phrase = "Je m'appelle {user} et j'ai {age} ans. {user} apprends le langage {learning}.".format(user=prenom,
                                                                                                age=age,
                                                                                                learning=langage)

👉 La méthode format permet donc d'obtenir un code beaucoup plus facile à lire et évite de s'embêter avec les fonctions de conversion.

Si on reprend l'exemple de l'URL du début de l'article :

protocole = "https://"
nom_du_site = "Docstring"
extension = "fr"

# Avec l'opérateur +
url = protocole + "www." + nom_du_site + "." + extension

# Avec la méthode format
url = "{}www.{}.{}".format(protocole, nom_du_site, extension)
url = "{protocole}www.{domaine}.{extension}".format(protocole=protocole,
                                                    domaine=nom_du_site,
                                                    extension="fr")
Les f-string

Depuis la version 3.6 de Python, une fonctionnalité très intéressante a fait son apparition : les f-string.

Derrière ce nom un peu bizarre se trouve une façon très efficace de formater des chaînes de caractères.

C'est vrai autant pour la lisibilité que pour les performances, qui seront meilleures qu'avec la méthode format (ça reste de l'ordre du millième de milliseconde mais tout de même).

Pour utiliser les f-string, il suffit de rajouter la lettre f devant votre chaîne de caractères :

phrase = f"Je suis un f-string."

On peut ensuite, comme avec la méthode format, insérer des données dans la chaîne de caractères avec les accolades.

La différence majeure réside dans le fait qu'on peut écrire du code Python directement dans les accolades.

On retrouve donc la flexibilité de la méthode format mais avec quelque chose d'encore plus facile à lire.

Reprenons l'exemple de l'URL :

protocole = "https://"
nom_du_site = "Docstring"
extension = "fr"

url = f"{protocole}www.{nom_du_site}.{extension}"  # https://www.Docstring.fr

Vous souhaitez mettre le nom du site en minuscule ?

Aucun problème, on peut utiliser la méthode lower directement à l'intérieur du f-string :

protocole = "https://"
nom_du_site = "Docstring"
extension = "fr"

url = f"{protocole}www.{nom_du_site.lower()}.{extension}"  # https://www.docstring.fr

On peut insérer n'importe quel type d'objet dans un f-string sans que cela ne pose de problème à Python :

>>> liste = ['Pommes', 'Poires', 'Bananes']
>>> print(f"Voici votre liste de courses : {liste}")
Voici votre liste de courses : ['Pommes', 'Poires', 'Bananes']

Et comme toujours, on peut écrire du code Python directement à l'intérieur des accolades :

>>> liste = ['Pommes', 'Poires', 'Bananes']
>>> print(f"Voici votre liste de courses : {', '.join(liste)}")
Voici votre liste de courses : Pommes, Poires, Bananes
Faites attention cependant à garder un code facile à lire ! Ce n'est pas parce qu'on peut tout faire à l'intérieur d'un f-string qu'on doit le faire !

Par exemple, évitez de faire ceci :

liste = ['Pommes', 'Poires', 'Bananes']
print(f"Voici votre liste de courses : {', '.join([fruit.upper() if fruit.lower() == 'pommes' else fruit for fruit in liste])}")
# Voici votre liste de courses : POMMES, Poires, Bananes

Il vaut mieux découper un peu plus notre code pour le rendre plus lisible :

liste = ['Pommes', 'Poires', 'Bananes']
liste_final = [fruit.upper() if fruit.lower() == 'pommes' else fruit for fruit in liste]
liste_format = ', '.join(liste_final)
print(f"Voici votre liste de courses : {liste_format}")
# Voici votre liste de courses : POMMES, Poires, Bananes

Et si après ça vous oubliez d'acheter des pommes, je ne peux plus rien pour vous 🤷‍♂️

Pour finir, sachez qu'il est tout à fait possible de créer un f-string sur plusieurs lignes :

prenom = "Pierre"
phrase = (
  f"Bonjour {prenom} et "
  "bienvenue sur Docstring. "
  f"Passez une bonne journée {prenom} !"
)
# 'Bonjour Pierre et bienvenue sur Docstring. Passez une bonne journée Pierre !'
Les caractères spéciaux

Vous l'avez peut-être vu venir...

On utilise des accolades pour indiquer des emplacements à l'intérieur d'une chaîne de caractères.

Comment faire alors pour insérer des accolades 🤯 ?

👉 Facile, il suffit de les tripler !

>>> prenom = "Pierre"
>>> f"Je me nomme {{prenom}}"
'Je me nomme {prenom}'
>>> f"Je me nomme {{{prenom}}}"
'Je me nomme {Pierre}'
Si vous doublez les accolades, la variable ne sera pas évaluée (les accolades sont bien visibles mais on retrouve la chaîne de caractères prenom au lieu de sa valeur).

En triplant les accolades, on a bien des accolades qui entourent la valeur associée à la variable prenom.

👉 Faites attention également de varier les guillemets si vous utilisez du code Python à l'intérieur d'un f-string !

Par exemple, pour récupérer la clé d'un dictionnaire :

profession = {'Pierre': 'ingénieur'}
phrase = f"Pierre est {profession["Pierre"]}"
# SyntaxError: invalid syntax

Les guillemets ferment la chaîne de caractères et on se retrouve avec une erreur de syntaxe.

Il faut donc utiliser des guillemets simple (ou vice-versa) :

profession = {'Pierre': 'ingénieur'}
phrase = f"Pierre est {profession['Pierre']}"
phrase = f'Pierre est {profession["Pierre"]}'
Quelques options de formatage

Il est possible de spécifier des options de formatage avancées directement à l'intérieur des accolades.

Les options de formatages sont séparées des données par le symbole des deux-points :

La suite de cet article est réservée aux membres inscrits 😢

Cadenas Voir les formules disponibles