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_function
est 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
Enregistrer un commentaire