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.