¿Cómo puedo imprimir caracteres literales entre llaves en una cadena de Python y también usar .format en él?

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

me da Key Error: Hello\\

Quiero imprimir la salida: {Hello} 42

Schitti
fuente
1
Ver también: stackoverflow.com/questions/35574349
dreftymac
99
Para aquellos que desean evitar doblar las llaves ( {{ }}), use string.Template. Allí puede sustituir los identificadores de la forma $foo(útil para generar código LaTeX).
Ioannis Filippidis
Para aquellos que desean evitar duplicar llaves, y que no son reacios a agregar otra dependencia a sus proyectos de Python, también existe Jinja2 que resuelve definitivamente este problema, permitiendo la sintaxis delimitador de marcador de posición personalizado definido por el usuario.
dreftymac

Respuestas:

2072

Necesita duplicar {{y }}:

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

Aquí está la parte relevante de la documentación de Python para la sintaxis de cadenas de formato :

Las cadenas de formato contienen "campos de reemplazo" rodeados de llaves {}. Cualquier cosa que no esté contenida entre llaves se considera texto literal, que se copia sin cambios a la salida. Si necesita incluir un carácter de llave en el texto literal, se puede escapar doblando: {{y }}.

Greg Hewgill
fuente
264
Entonces, si desea imprimir "{42}", ¡lo usaría "{{{0}}}".format(42)!
hughes
77
¿Qué pasa si quieres una sola llave? "{ something { } {value}".format(42)no funciona
AJP
14
"{{" .format () y "}}". format () imprimen llaves simples. En su ejemplo: imprima "{{algo {{}} {0}". Format (42) imprimirá "{algo {} 42".
Mark Visser
2
¿Qué significa {0}eso?
CodyBugstein
66
@ Imray: se {0}refiere al primer argumento de .format(). Puede imprimir más de un valor {0} {1} {2}, siempre y cuando le dé el mismo número de argumentos .format(). Consulte docs.python.org/library/string.html#format-examples para ver ejemplos extensos.
Greg Hewgill
74

Te escapas doblando los frenos.

P.ej:

x = "{{ Hello }} {0}"
print(x.format(42))
Kamil Kisiel
fuente
60

Python 3.6+ (2017)

En las versiones recientes de Python se usarían cadenas f (ver también PEP498 ).

Con las cadenas f se debe usar doble {{o}}

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

produce el deseado

 {Hello} 42

Si necesita resolver una expresión entre paréntesis en lugar de usar texto literal, necesitará tres conjuntos de paréntesis:

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

produce

{hello}
Divenex
fuente
46

El OP escribió este comentario:

Intenté formatear un pequeño JSON para algunos propósitos, como este: '{"all": false, "selected": "{}"}'.format(data)para obtener algo como{"all": false, "selected": "1,2"}

Es bastante común que surja el problema de "frenos de escape" cuando se trata de JSON.

Sugiero hacer esto:

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

Es más limpio que la alternativa, que es:

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

Usar la jsonbiblioteca es definitivamente preferible cuando la cadena JSON se vuelve más complicada que el ejemplo.

twasbrillig
fuente
1
¡Amén! Puede parecer más trabajo, pero usar bibliotecas para hacer lo que se supone que deben hacer las bibliotecas en lugar de cortar esquinas ... hace mejores cosas.
Kaolin Fire
1
Pero el orden de las claves en un objeto Python no está garantizado ... Aún así, la biblioteca JSON está garantizada para serializarse de una manera JSON.
wizzwizz4
2
wizzwizz4: Buen punto. Desde Python 3.6 en adelante, los diccionarios están ordenados por inserción, por lo que no sería un problema. Las versiones de Python entre 2.7 y 3.5 pueden usar OrderedDict de la biblioteca de colecciones.
twasbrillig 01 de
24

Intenta hacer esto:

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

Prueba esto:

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

pajton
fuente
14

Aunque no es mejor, solo como referencia, también puede hacer esto:

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

Puede ser útil, por ejemplo, cuando alguien quiere imprimir {argument}. Es quizás más legible que'{{{}}}'.format('argument')

Tenga en cuenta que omite las posiciones de argumento (por ejemplo, en {}lugar de {0}) después de Python 2.7

George Aprilis
fuente
5

Si va a hacer esto mucho, podría ser bueno definir una función de utilidad que le permita utilizar sustitutos de llaves arbitrarios, 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}'

Tenga en cuenta que esto funcionará ya sea con corchetes que son una cadena de longitud 2 o un iterable de dos cadenas (para delimitadores de varios caracteres).

tvt173
fuente
Pensé en eso también. Por supuesto, eso también funcionará y el algoritmo es más simple. Pero, imagina que tienes mucho texto como este, y solo quieres parametrizarlo aquí y allá. Cada vez que cree una cadena de entrada, no querrá reemplazar todas esas llaves manualmente. Simplemente querrás 'colocar' tus parametrizaciones aquí y allá. En este caso, creo que este método es más fácil de pensar y lograr desde la perspectiva del usuario. Me inspiró el comando 'sed' de Linux que tiene capacidades similares para elegir arbitrariamente su delimitador en función de lo que sea conveniente.
tvt173
En resumen, prefiero que la función de utilidad sea un poco más compleja que tener un dolor en el uso de @ $$ cada vez. Avíseme si entendí mal su propuesta.
tvt173
Continué y agregué una breve demostración a mi espacio public.lab
dreftymac
3

Recientemente me encontré con esto, porque quería inyectar cadenas en JSON preformateado. Mi solución fue crear un método auxiliar, como este:

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

Luego puedes hacer algo como:

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

Hace el trabajo si el rendimiento no es un problema.

Kristján Valur
fuente
Simple y elegante para integrar en el código existente con poca modificación requerida. ¡Gracias!
Columna01
2

Si necesita mantener dos llaves en la cuerda, necesita 5 llaves en cada lado de la variable.

>>> myvar = 'test'
>>> "{{{{{0}}}}}".format(myvar)
'{{test}}'
Ricardo
fuente
Para aquellos que usan cadenas f, use 4 llaves en cada lado en lugar de 5
TerryA
0

La razón es que {}es la sintaxis de .format()lo que en su caso .format()no reconoce, {Hello}por lo que arrojó un error.

puedes anularlo usando llaves dobles {{}},

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

o

intente %sformatear el texto,

x = " { Hello } %s"
print x%(42)  
Mohideen bin Mohammed
fuente
0

Me topé con este problema al intentar imprimir texto, que puedo copiar y pegar en un documento de Latex. Extiendo esta respuesta y hago uso de los campos de reemplazo con nombre:

Digamos que desea imprimir un producto de múltiples variables con índices como ingrese la descripción de la imagen aquí, que en Latex sería $A_{ 0042 }*A_{ 3141 }*A_{ 2718 }*A_{ 0042 }$ El siguiente código hace el trabajo con campos con nombre para que para muchos índices permanezca legible:

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

Si desea imprimir solo una llave (por ejemplo {), puede usarla {{, y puede agregar más llaves más adelante en la cadena si lo desea. Por ejemplo:

>>> 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'
Luis Cabrera Benito
fuente
-1

Cuando solo intentas interpolar cadenas de código, te sugiero que uses jinja2, que es un motor de plantillas con todas las funciones para Python, es decir:

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

Por lo tanto, no se le exigirá que duplique las llaves como lo sugieren todas las otras respuestas

BPL
fuente
-3

Puede hacer esto utilizando el método de cadena sin procesar simplemente agregando el carácter 'r' sin comillas antes de la cadena.

# to print '{I am inside braces}'
print(r'{I am inside braces}')
Aggarwal duro
fuente
¡Hola! Es posible que desee volver a verificar eso; Impresiones Python 3.7 \{I am inside braces\}.
Teodor
1
@Teodor lo siento por eso. Ahora arreglé esto imprimiendo como cadena sin procesar.
Harsh Aggarwal