15 Punkte von GN⁺ 2025-04-22 | 2 Kommentare | Auf WhatsApp teilen
  • t-Strings sind eine in Python 3.14 neu eingeführte sichere und flexible Funktion zur String-Verarbeitung
  • Anders als bisherige f-Strings liefern t-Strings keinen String, sondern ein Template-Objekt zurück, wodurch sichere Verarbeitung ohne automatische Ausgabe möglich wird
  • t-Strings haben eine Struktur, mit der sich dynamische Eingaben für HTML, SQL usw. sicher escapen lassen
  • Das Konzept ähnelt den tagged templates in JavaScript und ermöglicht vielfältige Erweiterungen für Transformation und Verarbeitung
  • Wenn das Python-Ökosystem für Entwicklungstools diese Funktion gut unterstützt, könnte sie die web-/sicherheitsorientierte String-Verarbeitung stark verändern

Pythons neue Funktion: t-Strings (Template Strings)

  • Ab Python 3.14 werden Template Strings (t-Strings) mit der Syntax t"..." als offizielle Funktion eingeführt
  • Anders als bisherige f-Strings werden t-Strings nicht sofort als String, sondern als string.templatelib.Template-Objekt ausgewertet
  • Dieses Objekt benötigt vor der Ausgabe einen separaten Verarbeitungsschritt; dadurch werden sichere Behandlung und Transformation dynamischer Werte möglich

Warum können f-Strings riskant sein?

  • Weil f-Strings sofort zu Strings ausgewertet werden, können in Code mit Benutzereingaben SQL-Injection oder XSS auftreten
    • Beispiel: f"<div>{user_input}</div>" → schädlicher Code kann direkt eingefügt werden
  • t-Strings verzögern diese Auswertung, sodass sie nur nach expliziter Verarbeitung verwendet werden können

Beispielverwendung von t-Strings

  • Beispiel für HTML-Escaping:

    evil = "<script>alert('bad')</script>"  
    template = t"<p>{evil}</p>"  
    safe = html(template)  
    # safe ist "<p>&lt;script&gt;alert('bad')&lt;/script&gt;</p>"  
    
  • Auch komplexere Verarbeitung wie das automatische Einfügen von Attributen ist möglich:

    attributes = {"src": "roquefort.jpg", "alt": "Yum"}  
    template = t"<img {attributes} />"  
    element = html(template)  
    # Ergebnis: "<img src='roquefort.jpg' alt='Yum' />"  
    

Struktur und API

  • Das Template-Objekt stellt über die Attribute .strings und .values den Originaltext und die eingesetzten Werte getrennt bereit

  • Über das Attribut interpolations sind sogar Formatdetails wie !s, :>8 usw. zugänglich

  • Über Iteration kann auch ein gemischter Zustand aus Text und Werten direkt verarbeitet werden

  • Manuelle Erstellung ist ebenfalls möglich:

    from string.templatelib import Template, Interpolation  
    template = Template(  
      "Hello ",  
      Interpolation(value="World", expression="name"),  
      "!"  
    )  
    

Interessantes Beispiel: Pig-Latin-Konverter

  • Ein Beispiel, das den Inhalt eines Template-Objekts durchläuft und Wörter in Pig Latin umwandelt:

    def pig_latin(template: Template) -> str:  
        ...  
    name = "world"  
    template = t"Hello {name}!"  
    assert pig_latin(template) == "Hello orldway!"  
    

Zukünftige Entwicklung

  • t-Strings können Sicherheit und Erweiterbarkeit in die web-/sicherheitsorientierte String-Verarbeitung bringen
  • Es bleibt zu hoffen, dass Entwicklungstools wie black, ruff und VS Code Formatierung/Highlighting für t-Strings unterstützen
  • Da das Konzept den tagged templates entspricht, die JavaScript-Entwickler bereits kennen, ist die Einsatzmöglichkeit auch in verschiedenen Frameworks hoch

Zusammenarbeit mit der Entwickler-Community

  • Diese Funktion wurde durch die Beteiligung und Zusammenarbeit vieler Mitglieder der Python-Community fertiggestellt
  • Besonders erwähnt wird der Austausch mit zentralen Personen wie Jim, Paul, Koudai, Lysandros und Guido
  • PEP 750 und das zugehörige Beispiel-Repository sind auf GitHub zu finden

Die t-Strings-Funktion in Python 3.14 sichert Sicherheit und Erweiterbarkeit zugleich ab und ist ein wichtiger Sprung über die Grenzen bisheriger f-Strings hinaus

2 Kommentare

 
GN⁺ 2025-04-22
Hacker-News-Kommentare
  • Insgesamt ist dieses Feature ziemlich cool. Im Grunde verwandelt es Code wie diesen

    db.execute("QUERY WHERE name = ?", (name,))
    

    in Folgendes

    db.execute(t"QUERY WHERE name = {name}")
    

    Es stellt sich die Frage, ob dieser syntaktische Zucker den Aufwand durch die zusätzliche Komplexität als neues Sprachfeature wert ist. Ich denke, in diesem Fall ja, und zwar aus zwei Gründen

    • Es ist gut, dass Bibliotheksentwickler über die {}-Erweiterung damit machen können, was sie wollen, und das dürfte zu guten Anwendungsfällen führen
    • Die Template-Syntax sprachweit zu verallgemeinern, sodass alle Bibliotheken Probleme auf dieselbe Weise lösen, ist wahrscheinlich ebenfalls eine gute Sache
  • Ich hoffe auch, dass sich das Tooling-Ökosystem anpasst, um t-strings zu unterstützen. Zum Beispiel wäre es schön, wenn black und ruff den Inhalt von t-strings formatieren und vscode Inhalte gängiger Typen wie HTML oder SQL farblich hervorheben würden

    • Diese Sicht auf t-strings ist ziemlich seltsam. Die einzige Möglichkeit, daraus abzuleiten, dass ein Template-String in gültiges HTML oder SQL umgewandelt werden soll, wäre auf Basis der offensichtlichen Syntax des Strings, und das wäre nur ein Behelf und hat nichts mit dem Template-String-Feature selbst zu tun
    • In der Art, wie das Feature entworfen wurde, gibt es im String selbst keinen Hinweis darauf, welche Art von Inhalt es ist oder in was es am Ende umgewandelt wird. Alles wird von der Umwandlungsfunktion gehandhabt
    • Wie andere bereits ergänzt haben, hätte etwas wie sql”select * from {table}” das leisten können, aber es gibt keine Garantie, dass das im Template enthaltene durch die Umwandlungsfunktion in gültiges SQL umgewandelt wird. t“give me {table} but only {columns}” könnte nach der Verarbeitung des Templates in gültiges SQL umgewandelt werden
  • Könnte man eine saubere SQL-Syntax wie die folgende verwenden?

    city = 'London'
    min_age = 21
    # Find all users in London who are 21 or older:
    users = db.get(t'
      SELECT * FROM users
      WHERE city={city} AND age>{min_age}
    ')
    

    Wenn die Funktion db.get() Templates akzeptiert, dann ja. Das wäre die sauberste Art, SQL zu verwenden, die ich bisher gesehen habe

  • Persönlich scheint mir dieses Feature zu stark auf ein spezielles Problem fokussiert, um ein allgemeines Feature zu sein. Python wird immer größer. Wenn Leute fragen, ob Python leicht zu lernen und einfach sei, muss man sagen: „Die Grundlagen schon, aber die gesamte Sprache zu lernen ist es nicht“

    • In dieser Hinsicht ist Go interessant, weil dort fast jedes Feature abgelehnt wird. Ehrlich gesagt bin ich nicht sicher, ob Generics es wert sind, weil sie viel Komplexität hinzufügen. Ich denke, die allgemeine Idee, eine Sprache auf ihren ursprünglichen Fokus auszurichten, ist richtig. C++ wäre wohl der Extremfall, bei dem die Sprache selbst kaum noch der ähnelt, als was sie einmal begonnen hat
  • Große Diskussion (414 Punkte, vor 10 Tagen, 324 Kommentare) Link

  • Ziemlich cool. Wenn schon JS-Features portiert werden, bekommen wir dann als Nächstes Dictionary-Unpacking/Destructuring?

    • Ich wünsche mir dieses Feature so sehr. Es ist der Hauptgrund, warum ich zu JS zurückgehe
    >>> {a, b=45, c=None, **d} = {'a': 234, xzy: 32456}
    >>> print(a, b, c, d)
    234 45 None {'xyz': 32456}
    
  • Dass diese neue x-string-Funktion eingebaut ist, fühlt sich für mich wie ein „Trick“ an. Es wäre cool, wenn man so etwas tun könnte

    from foo import bar
    bar"zoop"
    
  • Zen of Python im Jahr 2025:

    There should be one-- and preferably only one --obvious way to do it.
    

    Python-String-Formatting im Jahr 2025:

    • t-strings
    • f-strings
    • %-operator
    • +-operator
    • str.format()
  • Ich verstehe nicht, wie sich das davon unterscheidet, eine Funktion auf das Template anzuwenden, statt sie auf eine f-string-Variable anzuwenden. Also warum nicht einfach statt

    evil = "<script>alert('bad')</script>"
    template = t"{evil}"
    safe = html(template)
    

    einfach so:

    evil = "<script>alert('bad')</script>"
    safe = f"{html(evil)}"
    

    Oder bevor man den f-string erstellt. Geht es einfach darum, dass man den Bereinigungs-/String-Manipulationsschritt nicht vergisst und dazu gezwungen wird?

  • Hallo! Ich habe diesen Beitrag geschrieben :-)

    • Ich bin etwas spät in die Diskussion gekommen und war ein wenig überrascht, dass dieser Beitrag auf HN trendete, aber ich beantworte gern Fragen. Ich werde versuchen, mich über den Tag hinweg immer mal wieder einzubringen