Wie kann ich wörtliche geschweifte Klammern in Python-Strings drucken und auch .format verwenden?


1507
x = " \{ Hello \} {0} "
print(x.format(42))

gibt mir : Key Error: Hello\\

Ich möchte die Ausgabe drucken: {Hello} 42



9
Für diejenigen, die das Verdoppeln von Klammern ( {{ }}) vermeiden möchten , verwenden Sie string.Template. Dort ersetzen Sie Bezeichner des Formulars $foo(praktisch zum Generieren von LaTeX-Code).
Ioannis Filippidis

Für diejenigen, die das Verdoppeln von geschweiften Klammern vermeiden möchten und nicht abgeneigt sind, ihren Python-Projekten eine weitere Abhängigkeit hinzuzufügen, gibt es auch Jinja2 , das dieses Problem definitiv löst, indem es eine benutzerdefinierte Syntax für benutzerdefinierte Platzhaltertrennzeichen zulässt.
Dreftymac

Antworten:


2067

Sie müssen das {{und verdoppeln }}:

>>> x = " {{ Hello }} {0} "
>>> print(x.format(42))
' { Hello } 42 '

Hier ist der relevante Teil der Python-Dokumentation für die Format-String-Syntax :

Formatzeichenfolgen enthalten "Ersatzfelder", die von geschweiften Klammern umgeben sind {}. Alles, was nicht in geschweiften Klammern enthalten ist, wird als wörtlicher Text betrachtet, der unverändert in die Ausgabe kopiert wird. Wenn Sie ein Klammerzeichen in den wörtlichen Text aufnehmen müssen, können Sie es durch Verdoppeln umgehen: {{und }}.


264
Wenn Sie also "{42}" drucken möchten, verwenden Sie "{{{0}}}".format(42)!
Hughes

7
Was ist, wenn Sie eine einzelne geschweifte Klammer wollen? "{ something { } {value}".format(42)funktioniert nicht
AJP

14
"{{" .format () und "}}". format () druckt einzelne geschweifte Klammern. In Ihrem Beispiel: print "{{etwas {{}} {0}". Format (42) druckt "{etwas {} 42".
Mark Visser

2
Was bedeutet das {0}?
CodyBugstein

6
@Imray: {0}bezieht sich auf das erste Argument zu .format(). Sie können mehr als einen Wert drucken, {0} {1} {2}solange Sie die gleiche Anzahl von Argumenten angeben .format(). Ausführliche Beispiele finden Sie unter docs.python.org/library/string.html#format-examples .
Greg Hewgill

74

Sie entkommen ihm, indem Sie die Zahnspange verdoppeln.

Z.B:

x = "{{ Hello }} {0}"
print(x.format(42))

60

Python 3.6+ (2017)

In den neueren Versionen von Python wurden F-Strings verwendet (siehe auch PEP498 ).

Bei F-Strings sollte man double {{oder verwenden}}

n = 42  
print(f" {{Hello}} {n} ")

erzeugt das gewünschte

 {Hello} 42

Wenn Sie einen Ausdruck in den Klammern auflösen müssen, anstatt Literaltext zu verwenden, benötigen Sie drei Sätze von Klammern:

hello = "HELLO"
print(f"{{{hello.lower()}}}")

produziert

{hello}

46

Das OP schrieb diesen Kommentar:

Ich habe versucht, einen kleinen JSON für einige Zwecke wie diesen zu formatieren: '{"all": false, "selected": "{}"}'.format(data)um so etwas zu bekommen{"all": false, "selected": "1,2"}

Es ist ziemlich häufig, dass beim Umgang mit JSON das Problem "Escape Braces" auftritt.

Ich schlage vor, dies zu tun:

import json
data = "1,2"
mydict = {"all": "false", "selected": data}
json.dumps(mydict)

Es ist sauberer als die Alternative:

'{{"all": false, "selected": "{}"}}'.format(data)

Die Verwendung der jsonBibliothek ist definitiv vorzuziehen, wenn die JSON-Zeichenfolge komplizierter als das Beispiel wird.


1
Amen! Es mag wie mehr Arbeit erscheinen, aber die Verwendung von Bibliotheken, um das zu tun, was Bibliotheken tun sollen, im Vergleich zu Ecken und Kanten ... sorgt für bessere Dinge.
Kaolin Feuer

1
Die Reihenfolge der Schlüssel in einem Python-Objekt kann jedoch nicht garantiert werden. Dennoch wird garantiert, dass die JSON-Bibliothek auf JSON-Weise serialisiert wird.
wizzwizz4

2
wizzwizz4: Guter Punkt. Ab Python 3.6 werden Wörterbücher nach Einfügungsreihenfolge sortiert, sodass dies kein Problem darstellt. Python-Versionen zwischen 2.7 und 3.5 können OrderedDict aus der Sammlungsbibliothek verwenden.
Twasbrillig

24

Versuchen Sie Folgendes:

x = " {{ Hello }} {0} "
print x.format(42)


14

Obwohl nicht besser, nur als Referenz, können Sie dies auch tun:

>>> x = '{}Hello{} {}'
>>> print x.format('{','}',42)
{Hello} 42

Dies kann beispielsweise nützlich sein, wenn jemand drucken möchte {argument}. Es ist vielleicht besser lesbar als'{{{}}}'.format('argument')

Beachten Sie, dass Sie nach Python 2.7 Argumentpositionen (z. B. {}anstelle von {0}) weglassen


5

Wenn Sie dies häufig tun, ist es möglicherweise sinnvoll, eine Dienstprogrammfunktion zu definieren, mit der Sie stattdessen beliebige Klammerersatzprodukte verwenden können, z

def custom_format(string, brackets, *args, **kwargs):
    if len(brackets) != 2:
        raise ValueError('Expected two brackets. Got {}.'.format(len(brackets)))
    padded = string.replace('{', '{{').replace('}', '}}')
    substituted = padded.replace(brackets[0], '{').replace(brackets[1], '}')
    formatted = substituted.format(*args, **kwargs)
    return formatted

>>> custom_format('{{[cmd]} process 1}', brackets='[]', cmd='firefox.exe')
'{{firefox.exe} process 1}'

Beachten Sie, dass dies entweder funktioniert, wenn Klammern eine Zeichenfolge mit der Länge 2 oder eine iterierbare Zeichenfolge mit zwei Zeichenfolgen sind (für Trennzeichen mit mehreren Zeichen).


Ich habe auch darüber nachgedacht. Das wird natürlich auch funktionieren und der Algorithmus ist einfacher. Stellen Sie sich jedoch vor, Sie haben viel Text wie diesen und möchten ihn nur hier und da parametrisieren. Jedes Mal, wenn Sie eine Eingabezeichenfolge erstellen, möchten Sie nicht alle diese Klammern manuell ersetzen. Sie möchten nur hier und da Ihre Parametrisierungen "einfügen". In diesem Fall denke ich, dass diese Methode aus Anwendersicht sowohl einfacher zu überlegen als auch zu erreichen ist. Ich wurde von Linux 'Befehl' sed 'inspiriert, der ähnliche Funktionen bietet, um Ihr Trennzeichen willkürlich basierend auf den praktischen Optionen auszuwählen.
tvt173

Kurz gesagt, ich möchte lieber, dass die Utility-Funktion etwas komplexer ist, als dass es ein Problem im @ $$ ist, sie jedes Mal zu verwenden. Bitte lassen Sie mich wissen, wenn ich Ihren Vorschlag falsch verstanden habe.
tvt173

Ich habe eine kurze Demo meiner public.lab Raum voraus gegangen und hat github.com/dreftymac/public.lab/blob/master/topic/python/...
dreftymac

3

Ich bin kürzlich darauf gestoßen, weil ich Strings in vorformatierten JSON einfügen wollte. Meine Lösung bestand darin, eine Hilfsmethode wie die folgende zu erstellen:

def preformat(msg):
    """ allow {{key}} to be used for formatting in text
    that already uses curly braces.  First switch this into
    something else, replace curlies with double curlies, and then
    switch back to regular braces
    """
    msg = msg.replace('{{', '<<<').replace('}}', '>>>')
    msg = msg.replace('{', '{{').replace('}', '}}')
    msg = msg.replace('<<<', '{').replace('>>>', '}')
    return msg

Sie können dann etwas tun wie:

formatted = preformat("""
    {
        "foo": "{{bar}}"
    }""").format(bar="gas")

Erledigt die Aufgabe, wenn die Leistung kein Problem darstellt.


Einfach UND elegant in den vorhandenen Code zu integrieren, ohne dass Änderungen erforderlich sind. Vielen Dank!
Column01

2

Wenn Sie zwei geschweifte Klammern in der Zeichenfolge behalten müssen, benötigen Sie 5 geschweifte Klammern auf jeder Seite der Variablen.

>>> myvar = 'test'
>>> "{{{{{0}}}}}".format(myvar)
'{{test}}'

Verwenden Sie für diejenigen, die F-Saiten verwenden, 4 geschweifte Klammern auf beiden Seiten anstelle von 5
TerryA

0

Grund ist, {}ist die Syntax von .format()so in Ihrem Fall .format()nicht zu erkennen, {Hello}so dass es einen Fehler warf.

Sie können es überschreiben, indem Sie doppelte geschweifte Klammern {{}} verwenden.

x = " {{ Hello }} {0} "

oder

versuchen Sie %sfür die Textformatierung,

x = " { Hello } %s"
print x%(42)  

0

Ich bin auf dieses Problem gestoßen, als ich versucht habe, Text zu drucken, den ich kopieren und in ein Latex-Dokument einfügen kann. Ich erweitere diese Antwort und benutze benannte Ersatzfelder:

Nehmen wir an, Sie möchten ein Produkt aus mehreren Variablen mit Indizes ausdrucken, z. B. Geben Sie hier die Bildbeschreibung einin Latex. $A_{ 0042 }*A_{ 3141 }*A_{ 2718 }*A_{ 0042 }$ Der folgende Code erledigt die Aufgabe mit benannten Feldern, damit es für viele Indizes lesbar bleibt:

idx_mapping = {'i1':42, 'i2':3141, 'i3':2178 }
print('$A_{{ {i1:04d} }} * A_{{ {i2:04d} }} * A_{{ {i3:04d} }} * A_{{ {i1:04d} }}$'.format(**idx_mapping))

-1

Wenn Sie (zum Beispiel ) nur eine geschweifte Klammer drucken möchten, {können Sie diese verwenden {{und später in der Zeichenfolge weitere Klammern hinzufügen, wenn Sie möchten. Zum Beispiel:

>>> f'{{ there is a curly brace on the left. Oh, and 1 + 1 is {1 + 1}'
'{ there is a curly brace on the left. Oh, and 1 + 1 is 2'

-1

Wenn Sie nur versuchen, Code-Strings zu interpolieren, würde ich die Verwendung von jinja2 vorschlagen, einer voll funktionsfähigen Vorlagen-Engine für Python, dh:

from jinja2 import Template

foo = Template('''
#include <stdio.h>

void main() {
    printf("hello universe number {{number}}");
}
''')

for i in range(2):
    print(foo.render(number=i))

Sie werden also nicht gezwungen, geschweifte Klammern zu duplizieren, wie die ganze Reihe anderer Antworten vermuten lässt


-3

Sie können dies tun, indem Sie die Raw-String-Methode verwenden, indem Sie einfach das Zeichen 'r' ohne Anführungszeichen vor dem String einfügen.

# to print '{I am inside braces}'
print(r'{I am inside braces}')

Hallo! Vielleicht möchten Sie das noch einmal überprüfen. Python 3.7 druckt \{I am inside braces\}.
Teodor

1
@Teodor Entschuldigung dafür. Jetzt habe ich dies behoben, indem ich als Rohzeichenfolge gedruckt habe.
Harte Aggarwal
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.