Come creo una stringa Python multilinea con variabili inline?


94

Sto cercando un modo pulito per utilizzare le variabili all'interno di una stringa Python multilinea. Diciamo che volevo fare quanto segue:

string1 = go
string2 = now
string3 = great

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

Sto cercando di vedere se c'è qualcosa di simile a $Perl per indicare una variabile nella sintassi di Python.

In caso contrario, qual è il modo più pulito per creare una stringa multilinea con variabili?

Risposte:


155

Il modo comune è la format()funzione:

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

Funziona bene con una stringa di formato multilinea:

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

Puoi anche passare un dizionario con variabili:

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

La cosa più vicina a ciò che hai chiesto (in termini di sintassi) sono le stringhe del modello . Per esempio:

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

Dovrei aggiungere però che la format()funzione è più comune perché è prontamente disponibile e non richiede una riga di importazione.


2
Potrebbe usare vars()o locals()come dizionario in questione
Ismail Badawi

2
@isbadawi Explicit è meglio di implicit. Meglio passare solo le variabili di cui hai bisogno. Se non sai di cosa hai bisogno, perché la stringa è fornita dall'utente, le "variabili" dovrebbero comunque essere elementi in un file dict.
agf

La seconda soluzione è la più pulita IMO. Il dizionario insieme al nome della variabile in chiaro dal dizionario all'interno del punto multilinea. Userò questo metodo. Grazie. Un sacco di ottime risposte anche di seguito, ma questo è stato perfetto.
evoluzione

@SimeonVisser, "string" .format (...) non è valido sulle versioni precedenti di python (ad esempio 2.4)
Oz123

Se si usano le parentesi graffe, è necessario eseguire l'escape come {{this}}.
Jonny

52

NOTA : il modo consigliato per eseguire la formattazione delle stringhe in Python è quello di utilizzare format(), come descritto nella risposta accettata . Conservo questa risposta come esempio della sintassi in stile C supportata.

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

Qualche lettura:


2
Questo non è proprio lo stesso perché l'OP vuole parametri con nome, non posizionali.
Ismail Badawi

1
È ancora una buona soluzione e per un'interpolazione multilinea è più diretta. Non devi importare nulla e utilizza la normale interpolazione Python.
unflores

4
" Probabilmente avresti potuto rispondere a questo con un po 'di ricerca su Google " Il che implica che non abbiamo trovato questo post dopo aver
cercato su

30

Puoi usare le stringhe f di Python 3.6 per le variabili all'interno di stringhe a più righe o lunghe a riga singola. È possibile specificare manualmente i caratteri di nuova riga utilizzando \n.

Variabili in una stringa multilinea

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)

Ci
andrò adesso andrò alla
grande

Variabili in una lunga stringa di una sola riga

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

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

print(singleline_string)

Andrò lì. Io andrò ora. grande.


In alternativa, puoi anche creare una stringa f su più righe con virgolette triple.

multiline_string = f"""I will {string1} there.
I will go {string2}.
{string3}."""

Ciò mantiene il tuo codice sorgente bello e in pre-Python3.6 puoi ottenere lo stesso effetto semplicemente facendo questo (set extra di parentesi e usando +per concatenare): stackoverflow.com/a/54564926/4561887
Gabriel Staples

La tripla citazione è di gran lunga preferita. Dovresti prima presentare quel modulo.
jpmc26

@ jpmc26 Ho presentato prima lo stile delle parentesi sulla base delle linee guida di PEP 8 per l'indentazione del codice . Perché sarebbe preferibile la tripla citazione?
Stevoisiak

10

Questo è quello che vuoi:

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

Nota che le virgolette triple """conservano le nuove righe, il che significa che c'è una nuova riga in più prima e dopomystring
Stevoisiak

Puoi usare .strip(), .rstrip()o .lstrip(), o ue un gioco tra virgolette triple per evitare di creare una nuova riga. mystring = "" "\ ABC \" ""
Havok

6

È possibile passare un dizionario format(), ogni nome di chiave diventerà una variabile per ogni valore associato.

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

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

print(multiline_string)


Inoltre è possibile passare a un elenco format(), il numero di indice di ciascun valore verrà utilizzato come variabili in questo caso.

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

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

print(multiline_string)


Entrambe le soluzioni precedenti produrranno lo stesso risultato:

Ci
andrò adesso andrò alla
grande


0

Se qualcuno è venuto qui dal client python-graphql alla ricerca di una soluzione per passare un oggetto come variabile, ecco cosa ho usato:

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

 query = gql(query)

Assicurati di evitare tutte le parentesi graffe come ho fatto io: "{{", "}}"


0

Le stringhe f , chiamate anche "stringhe letterali formattate", sono letterali stringa che hanno un fall'inizio; e parentesi graffe contenenti espressioni che verranno sostituite con i relativi valori.

Le stringhe f vengono valutate in fase di esecuzione.

Quindi il tuo codice può essere riscritto come:

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

E questo valuterà:

I will go there
I will go now
great

Puoi saperne di più qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.