web-dev-qa-db-fra.com

Chaînes f imbriquées

Grâce à Tweet de David Beazley , j'ai récemment découvert que les nouvelles chaînes f de Python 3.6 peuvent également être imbriquées:

>>> price = 478.23
>>> f"{f'${price:0.2f}':*>20s}"
'*************$478.23'

Ou:

>>> x = 42
>>> f'''-{f"""*{f"+{f'.{x}.'}+"}*"""}-'''
'-*+.42.+*-'

Bien que je sois surpris que cela soit possible, je ne sais pas dans quelle mesure cela est pratique, quand l'imbrication de chaînes f serait-elle utile? Quels cas d'utilisation cela peut-il couvrir?

Remarque: Le PEP lui-même ne mentionne pas les chaînes f imbriquées, mais il existe un cas de test spécifique .

43
alecxe

Je ne pense pas que les littéraux de chaîne formatés permettent l'imbrication (en imbriquant, je suppose que cela signifie f'{f".."}') est le résultat d'un examen attentif des cas d'utilisation possibles, je suis plus convaincu que c'est juste autorisé afin qu'ils soient conformes à leurs spécifications.

La spécification indique qu'ils prennent en charge les expressions Python entre crochets. Il est également indiqué que un littéral de chaîne formaté n'est en réalité qu'une expression qui est évaluée au moment de l'exécution (Voir ici , et ici ). Par conséquent, il est logique d'autoriser un littéral de chaîne formaté en tant qu'expression à l'intérieur d'un autre littéral de chaîne formaté, en l'interdisant annulerait la prise en charge complète des expressions Python.

Le fait que vous ne puissiez pas trouver les cas d'utilisation mentionnés dans la documentation (et que vous ne trouverez que les cas de test dans la suite de tests) est parce que c'est probablement un effet agréable (secondaire) de l'implémentation et non pas un cas d'utilisation motivant.

43

Je suppose que c'est pour passer les paramètres de formatage sur la même ligne et ainsi simplifier l'utilisation f-strings.

Par exemple:

>>> import decimal
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"
'result:      12.35'

Bien sûr, cela permet aux programmeurs d'écrire du code absolument illisible, mais ce n'est pas le but :)

9
Eugene Lisitsky

Je viens de découvrir quelque chose de similaire (je pense) et j'ai pensé partager.

Mon cas spécifique est une grosse instruction SQL sale où j'ai besoin conditionnellement de valeurs très différentes mais certaines chaînes sont les mêmes (et également utilisées dans d'autres endroits).

Voici un exemple rapide de ce que je veux dire. Les colonnes que je sélectionne sont les mêmes (et également utilisées dans d'autres requêtes ailleurs), mais le nom de la table dépend du groupe et n'est pas tel que je pourrais simplement le faire en boucle.

Devoir inclure mycols=mycols en str2 à chaque fois, je me sentais un peu sale quand j'ai plusieurs de ces paramètres.

Je n'étais pas sûr que cela fonctionnerait, mais j'étais content que ce soit le cas. Quant à la façon dont Pythonic est, je ne suis pas vraiment sûr de tbh.

mycols='col_a,col_b'

str1 = "select {mycols} from {mytable} where group='{mygroup}'".format(mycols=mycols,mytable='{mytable}',mygroup='{mygroup}')

group = 'group_b'

if group == 'group_a':
    str2 = str1.format(mytable='tbl1',mygroup=group)
Elif group == 'group_b':
    str2 = str1.format(mytable='a_very_different_table_name',mygroup=group)

print(str2)
5
andrewm4894

Travaillant sur un projet pour animaux de compagnie, j'ai été détourné en écrivant ma propre bibliothèque de bases de données. J'ai découvert une chose:

>>> x = dict(a = 1, b = 2, d = 3)
>>> z = f"""
    UPDATE TABLE 
        bar 
    SET 
        {", ".join([ f'{k} = ?'     for k in x.keys() ])} """.strip()
>>> z
'UPDATE TABLE 
    bar 
SET 
    a = ?, b = ?, d = ?  '

J'ai également été surpris par cela et honnêtement, je ne suis pas sûr de pouvoir faire quelque chose comme ça dans le code de production MAIS j'ai également dit que je ne ferais pas beaucoup d'autres choses dans le code de production.

2
David