Como posso imprimir caracteres literais entre chaves na string python e também usar .format?


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

me dá: Key Error: Hello\\

Quero imprimir a saída: {Hello} 42



9
Para aqueles que querem evitar o uso de chaves ( {{ }}), use string.Template. Lá você substitui os identificadores do formulário $foo(útil para gerar o código LaTeX).
— Ioannis Filippidis

Para aqueles que desejam evitar o uso de chaves duplicadas e não têm aversão a adicionar outra dependência aos seus projetos em Python, também existe o Jinja2 que resolve definitivamente esse problema, permitindo a sintaxe do delimitador de marcador de posição personalizado definido pelo usuário.
— dreftymac 15/01

Respostas:


2071

Você precisa dobrar o {{e }}:

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

Aqui está a parte relevante da documentação do Python para a sintaxe da string de formato :

As seqüências de formato contêm "campos de substituição" cercados por chaves {}. Tudo o que não está contido entre chaves é considerado texto literal, que é copiado inalterado para a saída. Se você precisar incluir um caractere de colchete no texto literal, ele poderá ser escapado dobrando: {{e }}.


264
Então, se você quiser imprimir "{42}", você usaria "{{{0}}}".format(42)!
— 239 hughes

7
E se você quiser um único aparelho? "{ something { } {value}".format(42)não funciona
— AJP

14
"{{" .format () e "}}". format () imprimem chaves simples. No seu exemplo: print "{{something {{}} {0}". Format (42) imprimirá "{something {} 42".
— Mark Visser

2
O que {0}significa isso?
— CodyBugstein

6
@ Imray: {0}refere-se ao primeiro argumento para .format(). Você pode imprimir mais de um valor {0} {1} {2}, desde que dê o mesmo número de argumentos .format(). Veja docs.python.org/library/string.html#format-examples para exemplos extensos.
— Greg Hewgill

74

Você foge dobrando o aparelho.

Por exemplo:

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

60

Python 3.6+ (2017)

Nas versões recentes do Python, usaria -se strings-f (veja também PEP498 ).

Com as cordas f, deve-se usar o dobro {{ou}}

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

produz o desejado

 {Hello} 42

Se você precisar resolver uma expressão entre colchetes, em vez de usar texto literal, precisará de três conjuntos de colchetes:

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

produz

{hello}

46

O OP escreveu este comentário:

Eu estava tentando formatar um pequeno JSON para alguns propósitos, como este: '{"all": false, "selected": "{}"}'.format(data)para obter algo como{"all": false, "selected": "1,2"}

É bastante comum que o problema de "escapamento de aparelho" surja ao lidar com o JSON.

Eu sugiro fazer isso:

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

É mais limpo que a alternativa, que é:

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

O uso da jsonbiblioteca é definitivamente preferível quando a string JSON fica mais complicada que o exemplo.


1
Amém! Pode parecer mais trabalhoso, mas o uso de bibliotecas para fazer o que as bibliotecas devem fazer em comparação com as que cortam os cantos ... contribui para coisas melhores.
— quer

1
Mas a ordem das chaves em um objeto Python não é garantida ... Ainda assim, é garantido que a biblioteca JSON serialize de maneira JSON.
— wizzwizz4

2
wizzwizz4: Bom ponto. A partir do Python 3.6 em diante, os dicionários são ordenados por inserção, portanto não seria um problema. Versões do Python entre 2.7 e 3.5 podem usar OrderedDict da biblioteca de coleções.
— Twsbrillig 01/07/19

24

Tente fazer isso:

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


14

Embora não seja melhor, apenas para referência, você também pode fazer isso:

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

Pode ser útil, por exemplo, quando alguém deseja imprimir {argument}. Talvez seja mais legível do que'{{{}}}'.format('argument')

Observe que você omite as posições dos argumentos (por exemplo, em {}vez de {0}) após o Python 2.7


5

Se você fará muito isso, talvez seja bom definir uma função de utilitário que permita o uso de substitutos de chaves arbitrários, como

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

Observe que isso funcionará com parênteses sendo uma sequência de comprimento 2 ou iterável de duas seqüências (para delimitadores de vários caracteres).


Pensou sobre isso também. Obviamente, isso também funcionará e o algoritmo é mais simples. Mas imagine que você tenha um monte de texto como esse e queira apenas parametrizá-lo aqui e ali. Toda vez que você cria uma string de entrada, não deseja substituir todos esses aparelhos manualmente. Você gostaria apenas de 'soltar' suas parametrizações aqui e ali. Nesse caso, acho que esse método é mais fácil de se pensar e realizar da perspectiva do usuário. Fui inspirado pelo comando 'sed' do linux, que possui recursos semelhantes para escolher arbitrariamente seu delimitador com base no que for conveniente.
— Tvt173

Em suma, eu prefiro que a função de utilidade seja um pouco mais complexa do que uma dor no @ $$ usar sempre. Por favor, deixe-me saber se eu não entendi sua proposta.
— Tvt173

Fui em frente e adicionei uma breve demonstração ao meu espaço public.lab github.com/dreftymac/public.lab/blob/master/topic/python/…
— dreftymac

3

Recentemente, me deparei com isso, porque queria inserir seqüências de caracteres no JSON pré-formatado. Minha solução foi criar um método auxiliar, assim:

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

Você pode fazer algo como:

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

Realiza o trabalho se o desempenho não for um problema.


Simples e elegante para integrar no código existente, com poucas modificações necessárias. Obrigado!
— Column01

2

Se você precisar manter duas chaves na cadeia, precisará de 5 chaves em cada lado da variável.

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

Para aqueles usando f-cordas, utilizar 4 chavetas em ambos os lados, em vez de 5
— TerryA

0

A razão é que, {}a sintaxe de .format()que, no seu caso .format(), não reconhece {Hello}, gerou um erro.

você pode substituí-lo usando chaves duplas {{}},

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

ou

tente %sformatar o texto,

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

0

Eu me deparei com esse problema ao tentar imprimir texto, que eu posso copiar e colar em um documento de látex. Eu estendo esta resposta e utilizo os campos de substituição nomeados:

Digamos que você queira imprimir um produto de várias variáveis ​​com índices como insira a descrição da imagem aqui, o que no Latex seria $A_{ 0042 }*A_{ 3141 }*A_{ 2718 }*A_{ 0042 }$ O código a seguir faz o trabalho com campos nomeados para que, para muitos índices, fique legível:

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

Se você quiser imprimir apenas uma chave (por exemplo {) {{, use , e poderá adicionar mais chaves posteriormente na sequência, se desejar. Por exemplo:

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

Quando você está apenas tentando interpolar cadeias de código, sugiro usar o jinja2, que é um mecanismo de modelo completo para Python, ou seja:

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

Portanto, você não será obrigado a duplicar chaves, como sugerem várias outras respostas


-3

Você pode fazer isso usando o método de string bruto, simplesmente adicionando o caracter 'r' sem aspas antes da string.

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

Olá! Você pode verificar novamente isso; Impressões Python 3.7\{I am inside braces\} .
— Teodor

1
@ Tyodor desculpe por isso. Agora eu corrigi isso imprimindo como string não processada.
— Harsh Aggarwal
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.