Comment reporter/différer l'évaluation des f-strings ?

J'utilise des chaînes de modèle pour générer des fichiers et j'aime la concision des nouvelles chaînes f à cet effet, pour réduire mon code de modèle précédent à partir de quelque chose comme ceci :

template_a = "The current name is {name}"
names = ["foo", "bar"]
for name in names:
print (template_a.format(**locals()))

Maintenant, je peux le faire, en remplaçant directement les variables :

names = ["foo", "bar"]
for name in names:
print (f"The current name is {name}")

Cependant, il est parfois logique d'avoir le modèle défini ailleurs - plus haut dans le code, ou importé à partir d'un fichier ou quelque chose. Cela signifie que le modèle est une chaîne statique contenant des balises de formatage. Quelque chose devrait arriver à la chaîne pour dire à l'interpréteur d'interpréter la chaîne comme une nouvelle chaîne f, mais je ne sais pas s'il existe une telle chose.

Existe-t-il un moyen d'introduire une chaîne et de la faire interpréter comme une chaîne f pour éviter d'utiliser l' .format(**locals())appel?

Idéalement, je veux pouvoir coder comme ça... (où magic_fstring_functionest la partie que je ne comprends pas):

template_a = f"The current name is {name}"
# OR [Ideal2] template_a = magic_fstring_function(open('template.txt').read())
names = ["foo", "bar"]
for name in names:
print (template_a)

... avec cette sortie souhaitée (sans lire le fichier deux fois):

The current name is foo
The current name is bar

... mais la sortie réelle que j'obtiens est:

The current name is {name}
The current name is {name}


Solution du problème

Une manière concise d'avoir une chaîne évaluée comme une f-string (avec toutes ses capacités) utilise la fonction suivante :

def fstr(template):
return eval(f"f'{template}'")

Ensuite tu peux faire:

template_a = "The current name is {name}"
names = ["foo", "bar"]
for name in names:
print(fstr(template_a))
# The current name is foo
# The current name is bar

Et, contrairement à de nombreuses autres solutions proposées, vous pouvez également faire:

template_b = "The current name is {name.upper() * 2}"
for name in names:
print(fstr(template_b))
# The current name is FOOFOO
# The current name is BARBAR

Commentaires

Posts les plus consultés de ce blog

Comment signer la connexion OKEx API version 5 avec websockets ?

La fonction GCP Cloud pour écrire des données dans BigQuery s'exécute avec succès, mais les données n'apparaissent pas dans la table BigQuery

Erreur Symfony : "Une exception a été levée lors du rendu d'un modèle"