¿Cómo creo una cadena de Python multilínea con variables en línea?

103

Estoy buscando una forma limpia de usar variables dentro de una cadena de Python multilínea. Digamos que quería hacer lo siguiente:

string1 = go
string2 = now
string3 = great

"""
I will $string1 there
I will go $string2
$string3
"""

Estoy buscando para ver si hay algo similar a $en Perl para indicar una variable en la sintaxis de Python.

Si no es así, ¿cuál es la forma más limpia de crear una cadena de varias líneas con variables?

evolución
fuente

Respuestas:

159

La forma común es la format()función:

>>> s = "This is an {example} with {vars}".format(vars="variables", example="example")
>>> s
'This is an example with variables'

Funciona bien con una cadena de formato de varias líneas:

>>> s = '''\
... This is a {length} example.
... Here is a {ordinal} line.\
... '''.format(length='multi-line', ordinal='second')
>>> print(s)
This is a multi-line example.
Here is a second line.

También puede pasar un diccionario con variables:

>>> d = { 'vars': "variables", 'example': "example" }
>>> s = "This is an {example} with {vars}"
>>> s.format(**d)
'This is an example with variables'

Lo más parecido a lo que preguntó (en términos de sintaxis) son las cadenas de plantillas . Por ejemplo:

>>> from string import Template
>>> t = Template("This is an $example with $vars")
>>> t.substitute({ 'example': "example", 'vars': "variables"})
'This is an example with variables'

Sin embargo, debo agregar que la format()función es más común porque está disponible y no requiere una línea de importación.

Simeon Visser
fuente
2
Podría usar vars()o locals()como el diccionario en cuestión
Ismail Badawi
2
@isbadawi Explícito es mejor que implícito. Es mejor pasar solo las variables que necesita. Si no sabe cuál necesita, porque la cadena la proporciona el usuario, las "variables" deberían ser elementos de dicttodos modos.
agf
La segunda solución es la más limpia en mi opinión. El diccionario junto con el nombre claro de la variable del diccionario dentro de la línea multilínea. Usaré este método. Gracias. Un montón de excelentes respuestas a continuación también, pero esto fue perfecto.
evolución
@SimeonVisser, "string" .format (...) no es válido en versiones heredadas de Python (por ejemplo, 2.4)
Oz123
Si usa llaves, deben escaparse como {{this}}.
Jonny
54

NOTA : La forma recomendada de formatear cadenas en Python es usar format(), como se describe en la respuesta aceptada . Conservo esta respuesta como un ejemplo de la sintaxis de estilo C que también es compatible.

# NOTE: format() is a better choice!
string1 = "go"
string2 = "now"
string3 = "great"

s = """
I will %s there
I will go %s
%s
""" % (string1, string2, string3)

print(s)

Algo de lectura:

David Caín
fuente
2
Esto no es realmente lo mismo porque el OP quiere parámetros con nombre, no posicionales.
Ismail Badawi
2
Sigue siendo una buena solución y para una interpolación de varias líneas es más directa. No tiene que importar nada y utiliza la interpolación de Python regular.
florece el
4
" Probablemente podrías haber respondido a esta pregunta con un poco de búsqueda en Google ", lo que implica que no encontramos esta publicación después de buscar en Google ...
Stevoisiak
32

Puede usar cadenas f de Python 3.6 para variables dentro de cadenas de varias líneas o cadenas largas de una sola línea. Puede especificar manualmente caracteres de nueva línea usando \n.

Variables en una cadena de varias líneas

string1 = "go"
string2 = "now"
string3 = "great"

multiline_string = (f"I will {string1} there\n"
                    f"I will go {string2}.\n"
                    f"{string3}.")

print(multiline_string)

Iré allí
iré ahora
genial

Variables en una cadena larga de una sola línea

string1 = "go"
string2 = "now"
string3 = "great"

singleline_string = (f"I will {string1} there. "
                     f"I will go {string2}. "
                     f"{string3}.")

print(singleline_string)

Iré allí. Iré ahora. estupendo.


Alternativamente, también puede crear una cadena f de varias líneas con comillas triples.

multiline_string = f"""I will {string1} there.
I will go {string2}.
{string3}."""
Stevoisiak
fuente
Esto mantiene su código fuente con un aspecto atractivo, y en versiones anteriores a Python3.6 puede obtener el mismo efecto simplemente haciendo esto (conjunto adicional de paréntesis y uso +para concatenar): stackoverflow.com/a/54564926/4561887
Gabriel Staples
Se prefiere ampliamente la cotización triple . Primero debe presentar ese formulario.
jpmc26
@ jpmc26 Primero presenté el estilo de paréntesis basado en las pautas de PEP 8 para la sangría del código . ¿Por qué se preferiría la cotización triple?
Stevoisiak
10

Esto es lo que quieres:

>>> string1 = "go"
>>> string2 = "now"
>>> string3 = "great"
>>> mystring = """
... I will {string1} there
... I will go {string2}
... {string3}
... """
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, 'string3': 'great', '__package__': None, 'mystring': "\nI will {string1} there\nI will go {string2}\n{string3}\n", '__name__': '__main__', 'string2': 'now', '__doc__': None, 'string1': 'go'}
>>> print(mystring.format(**locals()))

I will go there
I will go now
great
Havok
fuente
Tenga en cuenta que las comillas triples """conservan las nuevas líneas, lo que significa que hay una nueva línea adicional antes y despuésmystring
Stevoisiak
Puede usar .strip(), .rstrip()o .lstrip(), o ue una reacción violenta dentro de las comillas triples para evitar crear una nueva línea. mystring = "" "\ ABC \" ""
Havok
6

Se puede pasar a un diccionario format(), cada nombre de clave se convertirá en una variable para cada valor asociado.

dict = {'string1': 'go',
        'string2': 'now',
        'string3': 'great'}

multiline_string = '''I'm will {string1} there
I will go {string2}
{string3}'''.format(**dict)

print(multiline_string)


También se puede pasar una lista format(), el número de índice de cada valor se utilizará como variables en este caso.

list = ['go',
        'now',
        'great']

multiline_string = '''I'm will {0} there
I will go {1}
{2}'''.format(*list)

print(multiline_string)


Ambas soluciones anteriores producirán lo mismo:

Voy a ir allí
voy a ir ahora
genial

bufón
fuente
1

Si alguien vino aquí desde el cliente python-graphql buscando una solución para pasar un objeto como variable, esto es lo que usé:

query = """
{{
  pairs(block: {block} first: 200, orderBy: trackedReserveETH, orderDirection: desc) {{
    id
    txCount
    reserveUSD
    trackedReserveETH
    volumeUSD
  }}
}}
""".format(block=''.join(['{number: ', str(block), '}']))

 query = gql(query)

Asegúrate de escapar de todas las llaves como hice yo: "{{", "}}"

Radu Ciobanu
fuente
1

f-strings , también llamados “literales de cadena formateados”, son literales de cadena que tienen un fal principio; y llaves que contienen expresiones que serán reemplazadas por sus valores.

Las cadenas f se evalúan en tiempo de ejecución.

Entonces su código se puede reescribir como:

string1="go"
string2="now"
string3="great"
print(f"""
I will {string1} there
I will go {string2}
{string3}
""")

Y esto evaluará a:

I will go there
I will go now
great

Puede obtener más información al respecto aquí .

Anshika Singh
fuente