Les f-strings de Python 3: une syntaxe de mise en forme des chaînes améliorée (Guide)

Les f-strings de Python 3: une syntaxe de mise en forme des chaînes améliorée (Guide)

Depuis Python 3.6, les chaînes f sont une excellente nouvelle façon de formater les chaînes. Non seulement ils sont plus lisibles, plus concis et moins sujets aux erreurs que les autres méthodes de formatage, mais ils sont également plus rapides!

À la fin de cet article, vous apprendrez comment et pourquoi commencer à utiliser des chaînes f dès aujourd’hui.

Mais d’abord, voici à quoi ressemblait la vie avant les cordes en f, à l’époque où vous deviez aller à l’école dans les deux sens dans la neige.

*Téléchargement PDF gratuit:* https://realpython.com/bonus/python-cheat-sheet-short/[Python 3 Cheat Sheet]

Formatage de chaîne «à l’ancienne» en Python

Avant Python 3.6, vous disposiez de deux manières principales d’incorporer des expressions Python dans des littéraux de chaîne pour le formatage:% -formatting et + str.format () +. Vous allez voir comment les utiliser et quelles sont leurs limites.

Option # 1: formatage en%

Il s’agit du format OG de Python et est dans la langue depuis le tout début. Vous pouvez en savoir plus dans les Python docs. Gardez à l’esprit que le formatage% n’est pas recommandé par les documents, qui contiennent la note suivante:

_ _ "Les opérations de mise en forme décrites ici présentent une variété de bizarreries qui conduisent à un certain nombre d’erreurs courantes (comme le fait de ne pas afficher correctement les tuples et les dictionnaires).

L’utilisation des nouveaux littéraux de chaîne formatés ou de l’interface + str.format () + permet d’éviter ces erreurs. Ces alternatives fournissent également des approches plus puissantes, flexibles et extensibles pour formater le texte. » (Source) _ _

Comment utiliser le formatage%

Les objets chaîne ont une opération intégrée utilisant l’opérateur +% +, que vous pouvez utiliser pour formater les chaînes. Voici à quoi cela ressemble en pratique:

>>>

>>> name = "Eric"
>>> "Hello, %s." % name
'Hello, Eric.'

Pour insérer plus d’une variable, vous devez utiliser un tuple de ces variables. Voici comment procéder:

>>>

>>> name = "Eric"
>>> age = 74
>>> "Hello, %s. You are %s." % (name, age)
'Hello Eric. You are 74.'
Pourquoi le formatage en% n’est pas génial

Les exemples de code que vous venez de voir ci-dessus sont suffisamment lisibles. Cependant, une fois que vous commencez à utiliser plusieurs paramètres et des chaînes plus longues, votre code deviendra rapidement beaucoup moins lisible. Les choses commencent déjà à paraître un peu désordonnées:

>>>

>>> first_name = "Eric"
>>> last_name = "Idle"
>>> age = 74
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> "Hello, %s %s. You are %s. You are a %s. You were a member of %s." % (first_name, last_name, age, profession, affiliation)
'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

Malheureusement, ce type de mise en forme n’est pas génial car il est détaillé et conduit à des erreurs, comme ne pas afficher correctement les tuples ou les dictionnaires. Heureusement, les jours sont meilleurs.

Option n ° 2: str.format ()

Cette nouvelle façon de faire le travail a été introduite dans Python 2.6. Vous pouvez consulter les Python docs pour plus d’informations.

Comment utiliser str.format ()

+ str.format () + est une amélioration par rapport au formatage en%. Il utilise la syntaxe d’appel de fonction normale et est https://www.python.org/dev/peps/pep-3101/#controlling-formatting-on-a-per-type-basis}extensible via le format `+ () + `méthode] sur l’objet en cours de conversion en chaîne.

Avec + str.format () +, les champs de remplacement sont marqués par des accolades:

>>>

>>> "Hello, {}. You are {}.".format(name, age)
'Hello, Eric. You are 74.'

Vous pouvez référencer des variables dans n’importe quel ordre en référençant leur index:

>>>

>>> "Hello, {1}. You are {0}.".format(age, name)
'Hello, Eric. You are 74.'

Mais si vous insérez les noms de variables, vous obtenez l’avantage supplémentaire de pouvoir passer des objets, puis de référencer des paramètres et des méthodes entre les accolades:

>>>

>>> person = {'name': 'Eric', 'age': 74}
>>> "Hello, {name}. You are {age}.".format(name=person['name'], age=person['age'])
'Hello, Eric. You are 74.'

Vous pouvez également utiliser + ** + pour effectuer cette astuce avec les dictionnaires:

>>>

>>> person = {'name': 'Eric', 'age': 74}
>>> "Hello, {name}. You are {age}.".format(**person)
'Hello, Eric. You are 74.'

+ str.format () + est certainement une mise à niveau par rapport au formatage%, mais ce n’est pas que des roses et du soleil.

Pourquoi str.format () n’est pas génial

Le code utilisant + str.format () + est beaucoup plus facile à lire que le code utilisant% -formatting, mais + str.format () + peut toujours être assez verbeux lorsque vous traitez plusieurs paramètres et des chaînes plus longues. Regarde ça:

>>>

>>> first_name = "Eric"
>>> last_name = "Idle"
>>> age = 74
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> print(("Hello, {first_name} {last_name}. You are {age}. " +
>>>        "You are a {profession}. You were a member of {affiliation}.") \
>>>        .format(first_name=first_name, last_name=last_name, age=age, \
>>>                profession=profession, affiliation=affiliation))
'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

Si vous aviez les variables que vous vouliez passer à + ​​.format () + dans un dictionnaire, alors vous pourriez simplement le décompresser avec + .format (* *some_dict) + et référencer les valeurs par clé dans la chaîne, mais il doit y avoir une meilleure façon de le faire.

f-Strings: une façon nouvelle et améliorée de formater les chaînes en Python

La bonne nouvelle est que les chaînes f sont là pour sauver la situation. Ils coupent! Ils dés! Ils font des frites julienne! D’accord, ils ne font rien de tout cela, mais ils facilitent le formatage. Ils ont rejoint le parti en Python 3.6. Vous pouvez tout lire à ce sujet dans PEP 498, qui a été écrit par Eric V. Smith en août 2015.

Aussi appelés «littéraux de chaîne formatés», les chaînes f sont des littéraux de chaîne qui ont un «+ f » au début et des accolades contenant des expressions qui seront remplacées par leurs valeurs. Les expressions sont évaluées au moment de l'exécution, puis formatées à l'aide du protocole ` format +`. Comme toujours, les Python docs sont votre ami lorsque vous voulez en savoir plus.

Voici quelques-unes des façons dont les cordes f peuvent vous faciliter la vie.

Syntaxe simple

La syntaxe est similaire à celle que vous avez utilisée avec + str.format () + mais moins verbeuse. Regardez à quel point cela est facilement lisible:

>>>

>>> name = "Eric"
>>> age = 74
>>> f"Hello, {name}. You are {age}."
'Hello, Eric. You are 74.'

Il serait également valable d’utiliser une majuscule + F +:

>>>

>>> F"Hello, {name}. You are {age}."
'Hello, Eric. You are 74.'

Aimez-vous encore les cordes en f? J’espère qu’à la fin de cet article, vous répondrez à https://twitter.com/dbader_org/status/992847368440561664 [+ >>> F" Oui! "+].

Expressions arbitraires

Étant donné que les chaînes f sont évaluées au moment de l’exécution, vous pouvez y placer toutes les expressions Python valides. Cela vous permet de faire des choses astucieuses.

Vous pouvez faire quelque chose d’assez simple, comme ceci:

>>>

>>> f"{2* 37}"
'74'

Mais vous pouvez également appeler des fonctions. Voici un exemple:

>>>

>>> def to_lowercase(input):
...     return input.lower()

>>> name = "Eric Idle"
>>> f"{to_lowercase(name)} is funny."
'eric idle is funny.'

Vous avez également la possibilité d’appeler directement une méthode:

>>>

>>> f"{name.lower()} is funny."
'eric idle is funny.'

Vous pouvez même utiliser des objets créés à partir de classes avec des chaînes f. Imaginez que vous ayez suivi le cours suivant:

class Comedian:
    def __init__(self, first_name, last_name, age):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

    def __str__(self):
        return f"{self.first_name} {self.last_name} is {self.age}."

    def __repr__(self):
        return f"{self.first_name} {self.last_name} is {self.age}. Surprise!"

Vous pourriez le faire:

>>>

>>> new_comedian = Comedian("Eric", "Idle", "74")
>>> f"{new_comedian}"
'Eric Idle is 74.'

Les méthodes + str () + et + repr () + traitent de la façon dont les objets sont présentés sous forme de chaînes, vous devrez donc vous assurer vous incluez au moins une de ces méthodes dans votre définition de classe. Si vous devez en choisir un, utilisez + repr () + car il peut être utilisé à la place de + str () +.

La chaîne renvoyée par + str () + est la représentation informelle de la chaîne d’un objet et doit être lisible. La chaîne renvoyée par + repr () + est la représentation officielle et ne doit pas être ambiguë. L’appel de + str () + et + repr () + est préférable à l’utilisation directe de + str () + et + repr () +.

Par défaut, les chaînes f utiliseront + str () +, mais vous pouvez vous assurer qu’elles utilisent + repr () + si vous incluez l’indicateur de conversion +! R +:

>>>

>>> f"{new_comedian}"
'Eric Idle is 74.'
>>> f"{new_comedian!r}"
'Eric Idle is 74. Surprise!'

Si vous souhaitez lire une partie de la conversation qui a abouti à des chaînes f prenant en charge les expressions Python complètes, vous pouvez le faire https://mail.python.org/pipermail/python-ideas/2015-July/034726.html [ ici].

Multiline f-Strings

Vous pouvez avoir des chaînes multilignes:

>>>

>>> name = "Eric"
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> message = (
...     f"Hi {name}. "
...     f"You are a {profession}. "
...     f"You were in {affiliation}."
... )
>>> message
'Hi Eric. You are a comedian. You were in Monty Python.'

Mais rappelez-vous que vous devez placer un + f + devant chaque ligne d’une chaîne multiligne. Le code suivant ne fonctionnera pas:

>>>

>>> message = (
...     f"Hi {name}. "
...     "You are a {profession}. "
...     "You were in {affiliation}."
... )
>>> message
'Hi Eric. You are a {profession}. You were in {affiliation}.'

Si vous ne mettez pas de "+ f +" devant chaque ligne individuelle, vous n’aurez alors que des cordes anciennes et variées de jardin et pas des cordes f brillantes, neuves et fantaisistes.

Si vous souhaitez étaler des chaînes sur plusieurs lignes, vous avez également la possibilité d’échapper un retour avec un + \ +:

>>>

>>> message = f"Hi {name}. " \
...           f"You are a {profession}. " \
...           f"You were in {affiliation}."
...
>>> message
'Hi Eric. You are a comedian. You were in Monty Python.'

Mais c’est ce qui se passera si vous utilisez `+" "" + `:

>>>

>>> message = f"""
...     Hi {name}.
...     You are a {profession}.
...     You were in {affiliation}.
... """
...
>>> message
'\n    Hi Eric.\n    You are a comedian.\n    You were in Monty Python.\n'

Lisez les lignes directrices sur l’indentation dans PEP 8.

La vitesse

Le + f + dans les chaînes f peut aussi bien signifier «rapide».

Les f-strings sont plus rapides que le formatage% et + str.format () +. Comme vous l’avez déjà vu, les chaînes f sont des expressions évaluées à l’exécution plutôt que des valeurs constantes. Voici un extrait de la documentation:

_ «Les chaînes F fournissent un moyen d’incorporer des expressions dans des littéraux de chaîne, en utilisant une syntaxe minimale. Il convient de noter qu’une chaîne f est vraiment une expression évaluée au moment de l’exécution, et non une valeur constante. Dans le code source Python, une chaîne f est une chaîne littérale, préfixée avec + f +, qui contient des expressions entre accolades. Les expressions sont remplacées par leurs valeurs. » (Source) _

Au moment de l’exécution, l’expression à l’intérieur des accolades est évaluée dans sa propre portée, puis assemblée avec la partie littérale de la chaîne f. La chaîne résultante est ensuite renvoyée. C’est tout ce qu’il faut.

Voici une comparaison de vitesse:

>>>

>>> import timeit
>>> timeit.timeit("""name = "Eric"
... age = 74
... '%s is %s.' % (name, age)""", number = 10000)
0.003324444866599663

>>>

>>> timeit.timeit("""name = "Eric"
... age = 74
... '{} is {}.'.format(name, age)""", number = 10000)
0.004242089427570761

>>>

>>> timeit.timeit("""name = "Eric"
... age = 74
... f'{name} is {age}.'""", number = 10000)
0.0024820892040722242

Comme vous pouvez le voir, les cordes f sortent en haut.

Mais cela n’a pas toujours été le cas. Lors de leur première mise en œuvre, ils avaient quelques https://stackoverflow.com/questions/37365311/why-are-literal-formatted-strings-so-slow-in-python-3-6-alpha-now-fixed-in -3-6 [problèmes de vitesse] et devait être rendu plus rapide que + str.format () +. Un https://bugs.python.org/issue27078 spécial [+ BUILD_STRING + opcode] a été introduit.

Python f-Strings: The Pesky Details

Maintenant que vous avez tout appris sur les raisons pour lesquelles les cordes f sont excellentes, je suis sûr que vous voulez vous lancer et commencer à les utiliser. Voici quelques détails à garder à l’esprit lorsque vous vous aventurez dans ce nouveau monde courageux.

Guillemets

Vous pouvez utiliser différents types de guillemets à l’intérieur des expressions. Assurez-vous simplement que vous n’utilisez pas le même type de guillemet à l’extérieur de la chaîne f que vous utilisez dans l’expression.

Ce code fonctionnera:

>>>

>>> f"{'Eric Idle'}"
'Eric Idle'

Ce code fonctionnera également:

>>>

>>> f'{"Eric Idle"}'
'Eric Idle'

Vous pouvez également utiliser des guillemets triples:

>>>

>>> f"""Eric Idle"""
'Eric Idle'

>>>

>>> f'''Eric Idle'''
'Eric Idle'

Si vous trouvez que vous devez utiliser le même type de guillemet à la fois à l’intérieur et à l’extérieur de la chaîne, vous pouvez vous échapper avec + \ +:

>>>

>>> f"The \"comedian\" is {name}, aged {age}."
'The "comedian" is Eric Idle, aged 74.'

Dictionnaires

En parlant de guillemets, faites attention lorsque vous travaillez avec des dictionnaires. Si vous prévoyez d’utiliser des guillemets simples pour les clés du dictionnaire, n’oubliez pas de vous assurer que vous utilisez des guillemets doubles pour les chaînes f contenant les clés.

Cela fonctionnera:

>>>

>>> comedian = {'name': 'Eric Idle', 'age': 74}
>>> f"The comedian is {comedian['name']}, aged {comedian['age']}."
The comedian is Eric Idle, aged 74.

Mais ce sera un gâchis chaud avec une erreur de syntaxe:

>>>

>>> comedian = {'name': 'Eric Idle', 'age': 74}
>>> f'The comedian is {comedian['name']}, aged {comedian['age']}.'
  File "<stdin>", line 1
    f'The comedian is {comedian['name']}, aged {comedian['age']}.'
                                    ^
SyntaxError: invalid syntax

Si vous utilisez le même type de guillemet autour des clés de dictionnaire que vous le faites à l’extérieur de la chaîne f, le guillemet au début de la première clé de dictionnaire sera interprété comme la fin de la chaîne.

Un appareil dentaire

Pour faire apparaître une accolade dans votre chaîne, vous devez utiliser des accolades doubles:

>>>

>>> f"{{74}}"
'{74}'

Notez que l’utilisation d’accolades triples entraînera la présence d’accolades simples dans votre chaîne:

>>>

>>> f"{{{74}}}"
'{74}'

Cependant, vous pouvez obtenir plus d’accolades à afficher si vous utilisez plus de trois accolades:

>>>

>>> f"{{{{74}}}}"
'{{74}}'

Contre-obliques

Comme vous l’avez vu précédemment, il vous est possible d’utiliser des échappements antislash dans la partie chaîne d’une chaîne f. Cependant, vous ne pouvez pas utiliser de barres obliques inverses pour vous échapper dans la partie expression d’une chaîne f:

>>>

>>> f"{\"Eric Idle\"}"
  File "<stdin>", line 1
    f"{\"Eric Idle\"}"
                      ^
SyntaxError: f-string expression part cannot include a backslash

Vous pouvez contourner cela en évaluant l’expression au préalable et en utilisant le résultat dans la chaîne f:

>>>

>>> name = "Eric Idle"
>>> f"{name}"
'Eric Idle'

Les expressions ne doivent pas inclure de commentaires utilisant le symbole + # +. Vous obtiendrez une erreur de syntaxe:

>>>

>>> f"Eric is {2 *37 #Oh my!}."
  File "<stdin>", line 1
    f"Eric is {2* 37 #Oh my!}."
                                ^
SyntaxError: f-string expression part cannot include '#'

Allez-y et formatez!

Vous pouvez toujours utiliser les anciennes méthodes de formatage des chaînes, mais avec les chaînes f, vous disposez désormais d’une méthode plus concise, lisible et pratique, à la fois plus rapide et moins sujette aux erreurs. Simplifier votre vie en utilisant des chaînes f est une excellente raison de commencer à utiliser Python 3.6 si vous n’avez pas déjà fait le changement. (Si vous utilisez toujours Python 2, n’oubliez pas que 2020 sera bientôt là!)

Selon le Zen of Python, lorsque vous devez décider comment faire quelque chose, alors «[t] ici devrait être un - et de préférence seulement une façon évidente de le faire. " Bien que les chaînes f ne soient pas le seul moyen possible de formater les chaînes, elles sont bien placées pour devenir le moyen évident de faire le travail.

Lectures complémentaires

Si vous souhaitez lire une discussion approfondie sur l’interpolation de chaînes, consultez PEP 502. En outre, le PEP 536 draft a quelques réflexions supplémentaires sur l’avenir des f-strings.

*Téléchargement PDF gratuit:* https://realpython.com/bonus/python-cheat-sheet-short/[Python 3 Cheat Sheet]

Pour plus de plaisir avec les cordes, consultez les articles suivants:

Pythoning heureux!