Jak mogę wydrukować dosłowne znaki nawiasu klamrowego w łańcuchu python, a także użyć na nim formatu .format?


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

daje mi : Key Error: Hello\\

Chcę wydrukować wynik: {Hello} 42



9
Dla tych, którzy chcą uniknąć podwajania nawiasów klamrowych ( {{ }}), użyj string.Template. Tam zastępujesz identyfikatory formularza $foo(przydatne do generowania kodu LaTeX).
Ioannis Filippidis

Dla tych, którzy chcą uniknąć podwajania nawiasów klamrowych i którzy nie mają nic przeciwko dodawaniu kolejnej zależności do swoich projektów w Pythonie, istnieje również Jinja2, która definitywnie rozwiązuje ten problem, umożliwiając zdefiniowaną przez użytkownika składnię ograniczników niestandardowych symboli zastępczych.
dreftymac

Odpowiedzi:


2066

Musisz podwoić {{i }}:

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

Oto odpowiednia część dokumentacji Pythona dotycząca składni ciągu formatu :

Ciągi formatujące zawierają „pola zastępcze” otoczone nawiasami klamrowymi {}. Wszystko, co nie jest zawarte w nawiasach klamrowych, jest uważane za dosłowny tekst, który jest kopiowany bez zmian do wyniku. Jeśli musisz wstawić znak nawiasu klamrowego w dosłownym tekście, można go uniknąć, podwajając: {{i }}.


264
Więc jeśli chcesz wydrukować „{42}”, skorzystaj "{{{0}}}".format(42)!
przytula

7
A co jeśli chcesz pojedynczy nawias klamrowy? "{ something { } {value}".format(42)nie działa
AJP

14
„{{” .format () i „}}”. format () drukuje pojedyncze nawiasy klamrowe. W twoim przykładzie: wypisz „{{coś {{}} {0}”. Format (42) wypisze „{coś {} 42”.
Mark Visser

2
Co {0}znaczy
CodyBugstein

6
@Imray: {0}odnosi się do pierwszego argumentu na .format(). Możesz wydrukować więcej niż jedną wartość, {0} {1} {2}pod warunkiem, że podasz taką samą liczbę argumentów .format(). Zobacz przykłady docs.python.org/library/string.html#format-examples .
Greg Hewgill,

74

Uciekasz mu, podwajając nawiasy klamrowe.

Na przykład:

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

60

Python 3.6+ (2017)

W najnowszych wersjach Pythona używa się f-stringów (patrz także PEP498 ).

W przypadku strun f należy stosować podwójne {{lub}}

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

produkuje pożądane

 {Hello} 42

Jeśli chcesz rozwiązać wyrażenie w nawiasach zamiast literalnego tekstu, potrzebujesz trzech zestawów nawiasów:

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

produkuje

{hello}

46

OP napisał ten komentarz:

Próbowałem sformatować mały JSON do niektórych celów, takich jak ten: '{"all": false, "selected": "{}"}'.format(data)aby uzyskać coś takiego{"all": false, "selected": "1,2"}

Podczas pracy z JSON często pojawia się problem „uciekających nawiasów klamrowych”.

Sugeruję zrobienie tego:

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

Jest czystszy niż alternatywa, czyli:

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

Korzystanie z jsonbiblioteki jest zdecydowanie lepsze, gdy łańcuch JSON staje się bardziej skomplikowany niż w przykładzie.


1
Amen! Może wydawać się, że to więcej pracy, ale używanie bibliotek do robienia tego, co biblioteki powinny robić, w porównaniu do wycinania rogów ... to lepsze rzeczy.
Kaolin Fire

1
Ale kolejność kluczy w obiekcie Python nie jest gwarantowana ... Mimo to biblioteka JSON gwarantuje serializację w sposób JSON.
wizzwizz4,

2
wizzwizz4: Dobra uwaga. Począwszy od Pythona 3.6, słowniki są uporządkowane według wstawiania, więc nie byłoby problemu. Wersje Pythona między wersjami 2.7 i 3.5 mogą korzystać z OrDERDict z biblioteki kolekcji.
twasbrillig

24

Spróbuj to zrobić:

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


14

Chociaż nie ma nic lepszego, tylko dla odniesienia, możesz również to zrobić:

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

Może być przydatny na przykład, gdy ktoś chce drukować {argument} . Być może jest bardziej czytelny niż'{{{}}}'.format('argument')

Zauważ, że pomijasz pozycje argumentów (np. {}Zamiast {0}) po Pythonie 2.7


5

Jeśli zamierzasz to często robić, dobrze jest zdefiniować funkcję narzędzia, która pozwoli ci zamiast tego używać dowolnych zamienników nawiasów klamrowych, takich jak

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}'

Zauważ, że zadziała to z nawiasami będącymi łańcuchem o długości 2 lub iterowalnym z dwóch łańcuchów (w przypadku ograniczników wieloznakowych).


Myślałem również o tym. Oczywiście to też zadziała, a algorytm jest prostszy. Ale wyobraź sobie, że masz taki tekst i po prostu chcesz go sparametryzować tu i tam. Za każdym razem, gdy tworzysz ciąg wejściowy, nie chcesz ręcznie zamieniać wszystkich tych nawiasów klamrowych. Po prostu chcesz „wpaść” w swoje parametry tutaj i tam. W tym przypadku myślę, że ta metoda jest łatwiejsza do myślenia i osiągania z perspektywy użytkownika. Zainspirowało mnie polecenie „sed” Linuksa, które ma podobne możliwości dowolnego wyboru ogranicznika na podstawie tego, co jest wygodne.
tvt173,

Krótko mówiąc, wolałbym, aby funkcja użyteczności była nieco bardziej złożona, niż korzystanie z @ $$ za każdym razem. Daj mi znać, jeśli źle zrozumiem twoją propozycję.
tvt173,

Dodałem krótkie demo do mojej publicznej przestrzeni github.com/dreftymac/public.lab/blob/master/topic/python/…
dreftymac,

3

Ostatnio na to wpadłem, ponieważ chciałem wstrzyknąć ciągi znaków do wstępnie sformatowanego JSON. Moim rozwiązaniem było stworzenie metody pomocniczej, takiej jak ta:

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

Następnie możesz zrobić coś takiego:

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

Wykonuje zadanie, jeśli wydajność nie stanowi problemu.


Prosty ORAZ elegancki do zintegrowania z istniejącym kodem, z niewielkimi modyfikacjami. Dzięki!
Kolumna 1

2

Jeśli potrzebujesz dwóch nawiasów klamrowych w ciągu, potrzebujesz 5 nawiasów klamrowych po każdej stronie zmiennej.

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

Dla osób używających stringów f, użyj 4 nawiasów klamrowych po obu stronach zamiast 5
TerryA

0

Powodem jest to, {}że składnia .format()tak, że w twoim przypadku .format()nie rozpoznaje, {Hello}więc zgłosił błąd.

możesz to zmienić, używając podwójnych nawiasów klamrowych {{}},

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

lub

spróbuj %ssformatować tekst,

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

0

Natknąłem się na ten problem, próbując wydrukować tekst, który mogę skopiować wklej do dokumentu lateksowego. Opieram się na tej odpowiedzi i korzystam z nazwanych pól zastępczych:

Powiedzmy, że chcesz wydrukować produkt wielu zmiennych z indeksami takimi jak wprowadź opis zdjęcia tutaj, którym w Lateksie byłoby: $A_{ 0042 }*A_{ 3141 }*A_{ 2718 }*A_{ 0042 }$ Poniższy kod wykonuje zadanie z nazwanymi polami, aby dla wielu indeksów był czytelny:

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

Jeśli chcesz wydrukować tylko jeden nawias klamrowy (na przykład {), możesz użyć {{i możesz dodać więcej nawiasów klamrowych później w ciągu, jeśli chcesz. Na przykład:

>>> 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

Gdy próbujesz interpolować ciągi kodu, sugeruję użycie jinja2, który jest w pełni funkcjonalnym silnikiem szablonów dla Pythona, tj .:

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))

Więc nie będziesz zmuszony do powielania nawiasów klamrowych, jak sugeruje cała masa innych odpowiedzi


-3

Możesz to zrobić, używając metody nieprzetworzonego ciągu, po prostu dodając znak „r” bez cudzysłowów przed ciągiem.

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

Dzień dobry! Możesz to sprawdzić ponownie; Wydruki w języku Python 3.7 \{I am inside braces\}.
Teodor

1
@ Teodor przepraszam za to. Teraz naprawiłem to, drukując jako nieprzetworzony ciąg.
Harsh Aggarwal,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.