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.