Les f-strings sont un moyen moderne et très pratique d’intégrer des valeurs de variables et des expressions directement dans le texte d’une chaîne de caractères. Pour créer une f-string, il suffit de placer la lettre f avant le guillemet d’ouverture. À l’intérieur de la chaîne, vous pouvez insérer des variables en les entourant d’accolades {}, et Python remplacera automatiquement {variable} par sa valeur.
<em># Créons deux variables avec des valeurs numériques.</em>
un = 1
deux = 2
<em># Insérons les valeurs des variables 'un' et 'deux' dans la chaîne.</em>
f"{un}, {deux}"
<em># Sortie : '1, 2'</em>
La puissance des f-strings réside dans leur capacité à contenir non seulement des variables, mais presque n’importe quelle expression Python valide à l’intérieur des accolades. Cela permet d’effectuer des calculs à la volée sans créer de variables intermédiaires inutiles.
<em># Effectuons une addition directement à l'intérieur de la f-string.</em>
f"{un} + {deux} = {un + deux}"
<em># Sortie : '1 + 2 = 3'</em>
Vous pouvez facilement accéder à des éléments de structures de données comme les dictionnaires (par clé) et les listes (par index) depuis une f-string. Cela s’étend également à l’accès aux attributs d’objets (en utilisant la notation par point) et même à l’appel de fonctions.
<em># Accès à la valeur d'un dictionnaire par sa clé.</em>
couleurs = {"rouge": "#ff0000", "vert": "#00ff00"}
f"La couleur rouge est {couleurs['rouge']}"
<em># Sortie : 'La couleur rouge est #ff0000'</em>
<em># Accès aux éléments d'une liste par leur index.</em>
donnees = [4, 8, 15, 16, 23, 42]
f"Les meilleurs nombres : {donnees[4]} et {donnees[5]}"
<em># Sortie : 'Les meilleurs nombres : 23 et 42'</em>
<em># Accès aux attributs d'un objet et appel de fonctions.</em>
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
pos = Point(23, 42)
f"Position : {pos.x}, {pos.y}. La plus grande valeur est {max(pos.x, pos.y)}."
<em># Sortie : 'Position : 23, 42. La plus grande valeur est 42.'</em>
Utiliser les f-strings pour le débogage
Depuis Python 3.8, les f-strings incluent un outil puissant pour le débogage rapide. En ajoutant un signe égal (=) après une variable ou une expression à l’intérieur des accolades, vous demandez à Python d’afficher non seulement la valeur, mais aussi l’expression elle-même. C’est incroyablement pratique pour inspecter rapidement le code.
from datetime import date, timedelta
utilisateur = "eric_idle"
membre_depuis = date(1975, 7, 31)
delta = date(2022, 4, 11) - membre_depuis
<em># Utilisez f"{utilisateur=}" pour obtenir automatiquement "utilisateur='eric_idle'".</em>
f"{utilisateur=} {membre_depuis=}"
<em># Sortie : "utilisateur='eric_idle' membre_depuis=datetime.date(1975, 7, 31)"</em>
Ce spécificateur de débogage peut être combiné avec des spécificateurs de formatage classiques. Vous pouvez également l’utiliser sur des expressions entières pour montrer clairement le calcul et son résultat.
<em># = montre le nom de la variable, : commence le formatage, ,d formate en entier avec séparateur de milliers.</em>
f"{delta.days=:,d}"
<em># Sortie : 'delta.days=17,056'</em>
<em># Montre à la fois l'entrée et le résultat d'un calcul.</em>
from math import cos, radians
theta = 30
f"{theta=} {cos(radians(theta))=:.3f}"
<em># Sortie : 'theta=30 cos(radians(theta))=0.866'</em>
Afficher les représentations de débogage (repr)
Les objets Python ont deux représentations textuelles : str() (pour un affichage convivial) et repr() (pour un affichage non ambigu, destiné aux développeurs). Par défaut, les f-strings utilisent str(). Pour obtenir la sortie de repr(), vous pouvez utiliser l’indicateur de conversion !r, qui est un raccourci pratique pour appeler repr() manuellement. L’indicateur !s appelle explicitement str().
class Donnee:
def __repr__(self): return '<Donnee ...>' <em># Représentation de débogage</em>
def __str__(self): return 'représentation textuelle' <em># Représentation utilisateur</em>
donnee = Donnee()
<em># Le comportement par défaut appelle str(donnee)</em>
f"donnee : {donnee}"
<em># Sortie : 'donnee : représentation textuelle'</em>
<em># Utiliser l'indicateur !r appelle repr(donnee)</em>
f"donnee : {donnee!r}"
<em># Sortie : 'donnee : <Donnee ...>'</em>
Remplissage, alignement et troncature
Les f-strings offrent un contrôle total sur le formatage de la sortie, y compris la largeur du champ, l’alignement et les caractères de remplissage. Le spécificateur de format est placé après un deux-points (:).
>aligne le texte à droite.<aligne le texte à gauche.^centre le texte.- Un nombre après le caractère d’alignement spécifie la largeur totale du champ.
- Un caractère avant le caractère d’alignement spécifie le caractère de remplissage.
val = "test"
<em># Aligner à droite dans un champ de 10 caractères</em>
f"{val:>10}"
<em># Sortie : ' test'</em>
<em># Aligner à gauche et remplir l'espace vide avec '_'</em>
f"{val:_<10}"
<em># Sortie : 'test______'</em>
<em># Centrer le texte</em>
f"{val:^10}"
<em># Sortie : ' test '</em>
Pour tronquer une chaîne à une longueur maximale, utilisez la syntaxe :.N, où N est le nombre de caractères.
instrument = "xylophone"
<em># Tronquer la chaîne à 5 caractères.</em>
f"{instrument:.5}"
<em># Sortie : 'xylop'</em>
Représentations numériques
De nombreuses options de formatage sont disponibles pour les nombres. Vous pouvez facilement convertir les nombres en binaire (b), octal (o) ou hexadécimal (x/X). L’utilisation d’un # ajoute le préfixe approprié (0b, 0o, 0x).
reponse = 42
<em># Représentation hexadécimale</em>
f"{reponse:x}, {reponse:X}"
<em># Sortie : '2a, 2A'</em>
<em># Avec un préfixe</em>
f"{reponse:#x}"
<em># Sortie : '0x2a'</em>
<em># Notation scientifique</em>
f"{reponse ** 8:e}"
<em># Sortie : '9.682652e+12'</em>
Le remplissage de nombres avec des zéros non significatifs se fait en utilisant 0 comme caractère de remplissage. Pour les nombres à virgule flottante, vous pouvez contrôler à la fois la largeur totale et le nombre de décimales. Vous pouvez également contrôler l’affichage du signe et ajouter des séparateurs de milliers.
<em># Remplir jusqu'à 4 chiffres avec des zéros non significatifs</em>
f"{reponse:04d}"
<em># Sortie : '0042'</em>
<em># Pour Pi : largeur totale 6, 2 décimales, remplissage avec des zéros</em>
import math
f"{math.pi:06.2f}"
<em># Sortie : '003.14'</em>
<em># Toujours afficher le signe (+ pour positif, - pour négatif)</em>
f"{reponse:+d}"
<em># Sortie : '+42'</em>
<em># Utiliser une virgule comme séparateur de milliers</em>
nombre = 1234567890
f"{nombre:,d}"
<em># Sortie : '1,234,567,890'</em>
Sujets supplémentaires et bonnes pratiques
De nombreux objets intégrés, comme datetime, ont leur propre mini-langage de formatage qui fonctionne directement à l’intérieur des f-strings.
from datetime import datetime
dt = datetime(2022, 4, 11, 13, 37)
<em># Utiliser les codes de formatage de date/heure standard</em>
f"{dt:%Y-%m-%d %H:%M}"
<em># Sortie : '2022-04-11 13:37'</em>
Les spécificateurs de format eux-mêmes n’ont pas besoin d’être statiques ! Vous pouvez les définir dynamiquement en utilisant des variables avec des accolades imbriquées.
<em># La largeur et l'alignement sont définis par des variables</em>
valeur = "test"
alignement = "^"
largeur = 10
<em># f'{valeur:{alignement}{largeur}}' devient d'abord f'{valeur:^10}'</em>
f'{valeur:{alignement}{largeur}}'
<em># Sortie : ' test '</em>
Si vous avez besoin d’inclure une accolade littérale { ou } dans votre chaîne, il suffit de la doubler.
f"Accolades littérales : {{valeur}}"
<em># Sortie : 'Accolades littérales : {valeur}'</em>
Conseils pratiques et pièges à éviter
Lisibilité contre concision
Les f-strings permettent d’intégrer des expressions très complexes, mais ce n’est pas toujours une bonne idée. Un principe fondamental de Python est la lisibilité du code.
Mauvaise pratique (difficile à lire) :
<em># Techniquement, ça fonctionne, mais que se passe-t-il ici ?</em>
print(f"Résultat : {round([user.height for user in users if user.active][0] / 2.54, 2)} pouces.")
Bonne pratique (séparer la logique de la présentation) :
<em># 1. D'abord, on prépare les données</em>
hauteurs_utilisateurs_actifs = [user.height for user in users if user.active]
hauteur_premier_utilisateur_cm = hauteurs_utilisateurs_actifs[0]
hauteur_en_pouces = round(hauteur_premier_utilisateur_cm / 2.54, 2)
<em># 2. Ensuite, on formate le résultat</em>
print(f"Résultat : {hauteur_en_pouces} pouces.")
```Le code est plus long, mais il est maintenant compréhensible, testable et facile à modifier. **Règle générale : si une expression à l'intérieur de `{}` dépasse 20-30 caractères ou contient une logique complexe, il est préférable de l'extraire dans une variable séparée.**
<em>#### F-strings multilignes</em>
Pour les chaînes longues ou pour générer du texte sur plusieurs lignes (par exemple, des requêtes SQL, des modèles HTML), utilisez des guillemets triples. Les expressions à l'intérieur peuvent également s'étendre sur plusieurs lignes.
```python
utilisateur = "hypo69"
permissions = ['read', 'write', 'execute']
<em># L'expression dans la f-string est répartie sur plusieurs lignes pour la lisibilité</em>
rapport = f"""
Rapport utilisateur : {utilisateur.upper()}
----------------------------------
Permissions : {', '.join(p for p in permissions
if p != 'execute')}
"""
print(rapport)
Problèmes de sécurité (Très important !)
Les f-strings en elles-mêmes sont sûres. Une expression comme f"Bonjour, {nom}" n’est pas une vulnérabilité ; Python se contente de prendre la représentation textuelle de nom.
Le danger survient lorsque vous combinez les f-strings avec des fonctions qui exécutent du code, comme eval().
CODE EXTRÊMEMENT DANGEREUX — NE FAITES JAMAIS CELA :
import os
modele_utilisateur = input("Entrez un modèle : ") <em># L'utilisateur entre : '{os.system("reboot")}'</em>
eval(f'f"{modele_utilisateur}"')
Si un utilisateur entre {os.system("reboot")}, votre serveur redémarrera. Il s’agit d’une vulnérabilité d’Exécution de Code à Distance (RCE). Ne passez jamais de chaînes fournies par un utilisateur à des fonctions comme eval(), même via des f-strings. Pour les modèles définis par l’utilisateur, utilisez des moteurs de templates sécurisés comme Jinja2.
Performance : pourquoi les f-strings sont-elles si rapides ?
Une f-string n’est pas un appel de fonction ; elle fait partie de la syntaxe de Python. Le compilateur analyse la f-string et la décompose en parties littérales et en expressions à évaluer. Ceci est compilé en un bytecode très efficace qui construit la chaîne finale en une seule opération rapide. C’est beaucoup plus rapide que la méthode .format(), qui doit analyser la chaîne de formatage au moment de l’exécution.
Outils de migration
Des outils comme flynt et pyupgrade peuvent convertir automatiquement du code ancien utilisant .format() et % vers les f-strings modernes, ce qui est un excellent moyen de moderniser rapidement une base de code héritée.