webentwicklung-frage-antwort-db.com.de

Verschachtelte F-Strings

Dank David Beazleys Tweet habe ich kürzlich herausgefunden, dass die neuen Python 3.6 f-Strings auch verschachtelt werden können:

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

Oder:

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

Ich bin zwar überrascht, dass dies möglich ist, aber ich vermisse, wie praktisch das ist. Wann wäre es sinnvoll, F-Strings zu verschachteln? Welche Anwendungsfälle kann dies abdecken?

Hinweis: Das PEP selbst erwähnt keine verschachtelten f-Strings, aber es gibt einen spezifischen Testfall .

43
alecxe

Ich glaube nicht, dass formatierte String-Literale das Verschachteln zulassen (ich nehme an, dass f'{f".."}') Das Ergebnis sorgfältiger Überlegungen möglicher Anwendungsfälle ist. Ich bin eher davon überzeugt, dass dies nur zulässig ist, damit sie es tun entsprechen ihrer Spezifikation.

Die Spezifikation besagt, dass sie volle Python Ausdrücke in Klammern unterstützen. Es wird auch angegeben, dass ein formatiertes Zeichenfolgenliteral eigentlich nur ein Ausdruck ist, der zur Laufzeit ausgewertet wird (siehe hier und hier ). Infolgedessen ist es nur sinnvoll, ein formatiertes Zeichenfolgenliteral als Ausdruck in einem anderen formatierten Zeichenfolgenliteral zuzulassen, da dies die vollständige Unterstützung für Python= - Ausdrücke negiert.

Die Tatsache, dass Sie in den Dokumenten erwähnte Anwendungsfälle nicht finden können (und nur Testfälle in der Testsuite finden können), liegt daran, dass dies wahrscheinlich ein netter (Neben-) Effekt der Implementierung ist und nicht ein motivierender Anwendungsfall.

Ich denke, dies ist Formatierungsparameter in der gleichen Zeile zu übergeben und damit F-Strings Verwendung zu vereinfachen.

Beispielsweise:

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

Natürlich erlaubt es Programmierern, absolut unlesbaren Code zu schreiben, aber das ist nicht der Zweck :)

9
Eugene Lisitsky

Ich bin gerade auf etwas Ähnliches gestoßen (glaube ich) und dachte, ich würde es teilen.

Mein spezieller Fall ist eine große schmutzige SQL-Anweisung, bei der ich bedingt einige sehr unterschiedliche Werte haben muss, aber einige fstrings gleich sind (und auch an anderen Stellen verwendet werden).

Hier ist ein kurzes Beispiel dafür, was ich meine. Die Spalten, die ich auswähle, sind die gleichen, unabhängig davon (und auch in anderen Abfragen an anderer Stelle verwendet), aber der Tabellenname hängt von der Gruppe ab und ist nicht so, dass ich es einfach in einer Schleife tun könnte.

mycols=mycols In str2 einschließen zu müssen, fühlte sich jedes Mal ein wenig schmutzig an, wenn ich mehrere solcher Parameter habe.

Ich war mir nicht sicher, ob das funktionieren würde, war aber froh, dass es so war. Was Pythonic angeht, bin ich mir nicht sicher.

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

Bei der Arbeit an einem Haustierprojekt wurde ich abgelenkt, als ich meine eigene DB-Bibliothek schrieb. Eines habe ich entdeckt:

>>> 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 = ?  '

Ich war auch überrascht und ehrlich gesagt bin ich mir nicht sicher, ob ich jemals so etwas im Produktionscode machen würde, ABER ich habe auch gesagt, ich würde nicht viele andere Dinge im Produktionscode machen.

2
David