String formattazione denominata parametri?


135

So che è una domanda davvero semplice, ma non ho idea di come cercarla su Google.

Come posso fare

print '<a href="%s">%s</a>' % (my_url)

Quindi my_urlviene usato due volte? Presumo che devo "nominare" il %se quindi usare un dict nei parametri, ma non sono sicuro della sintassi corretta?


solo FYI, sono consapevole che posso usare solo my_urldue volte nei parametri, ma non è questo il punto :)


Il titolo della domanda è un po 'fuorviante. Questo non ha nulla a che fare con l'istruzione print, solo con il modo in cui funziona l'interpolazione di stringhe.
Greg Ball

Quando non hai idea di come cercarlo su Google, vai qui per usare la ricerca: python.org/doc . È meglio di Google per un motivo importante.
S.Lott

Risposte:


80

In Python 2.6+ e Python 3, potresti scegliere di utilizzare il metodo di formattazione delle stringhe più recente.

print('<a href="{0}">{0}</a>'.format(my_url))

che ti salva dal ripetere l'argomento, o

print('<a href="{url}">{url}</a>'.format(url=my_url))

se vuoi parametri nominati.

print('<a href="{}">{}</a>'.format(my_url, my_url))

che è strettamente posizionale, e viene solo con l'avvertenza che gli argomenti format () seguono le regole di Python dove prima devono venire gli arg senza nome, seguiti dagli argomenti con nome, seguiti da * args (una sequenza come list o tuple) e poi * kwargs (un dict chiave con stringhe se sai cosa è buono per te). I punti di interpolazione sono determinati prima sostituendo i valori nominati nelle loro etichette, quindi posizionali da ciò che resta. Quindi, puoi anche farlo ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, my_url, not_my_url=her_url))

Ma non questo ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, not_my_url=her_url, my_url))

È bello vedere l'influenza passare da ++ a #
cod3monk3y,

3
Tuttavia, il metodo sopra non è per la formattazione di stringhe denominate , si tratta della formattazione di stringhe posizionali. Quindi questo non risponde davvero alla domanda.
Jaapz,

Il "literal {arg1}".format(arg1="arg!")formato denominato funziona con Python 3.5, mentre il terser f"literal {arg1}"è un'innovazione più recente in Python 3.6 o più recente, AFAIK.
MarkHu,

218
print '<a href="%(url)s">%(url)s</a>' % {'url': my_url}

3
Preferisco creare il dict con kwargs:'<a href="%(url)s">%(url)s</a>' % dict(url=my_url)
schlamar

11
Mi chiedo perché preferisci quella schmlamar? Non avrei prontamente saputo cosa significasse, rispetto alla normale dichiarazione di un dict che l'OP usa ...
GreenAsJade

1
La documentazione non dice quando è stato introdotto, quindi è probabilmente in tutte le versioni di Python 2.
Evgeni Sergeev,

2
Usa format () se puoi, funziona meglio e in più posti. Usa% se DEVI.
Uchuugaka,

39

Soluzione in Python 3.6+

Python 3.6 introduce la formattazione letterale della stringa , in modo da poter formattare i parametri nominati senza ripetere nessuno dei parametri nominati all'esterno della stringa:

print(f'<a href="{my_url:s}">{my_url:s}</a>')

Questo valuterà my_url, quindi se non è definito otterrai un NameError. In effetti, invece di my_url, puoi scrivere un'espressione Python arbitraria, purché restituisca una stringa (a causa del :scodice di formattazione). Se si desidera una rappresentazione in forma di stringa per il risultato di un'espressione che potrebbe non essere una stringa, sostituirla :scon !s, proprio come con una normale formattazione pre-letterale della stringa.

Per i dettagli sulla formattazione letterale delle stringhe, vedere PEP 498 , dove è stato introdotto per la prima volta.


1
Quel PEP non sembra coprire tutti i formattatori; Penso che siano gli stessi di str.format che è documentato qui: docs.python.org/3.4/library/string.html#formatstrings
mpen

6

Sarai dipendente dalla sintassi.

Anche C # 6.0, gli sviluppatori di EcmaScript hanno familiarizzato anche con questa sintassi.

In [1]: print '{firstname} {lastname}'.format(firstname='Mehmet', lastname='Ağa')
Mehmet Ağa

In [2]: print '{firstname} {lastname}'.format(**dict(firstname='Mehmet', lastname='Ağa'))
Mehmet Ağa

5

Per la creazione di pagine HTML, si desidera utilizzare un motore di template, non una semplice interpolazione di stringhe.


2
Il motore di template di Django potrebbe anche rivelarsi lo strumento ideale per le email che stai creando.
Mike Graham,

6
Cosa ti impedisce di utilizzare un modello Django per generare un corpo e-mail con il suo render()metodo? Nulla dice che devi alimentare l'output del modello HttpResponse(). Django è incredibilmente versatile.
Mike DeSimone,

1
@Mike: pensavo che anche Django potesse avere una soluzione per questo, ma non l'avevo ancora trovata: p probabilmente trasferirò le mie e-mail in modelli! Grazie. Forse sono tardivo, ma l'ho trovato piuttosto rigido in alcune aree.
aprono il

2
@Random persone che leggono questi commenti: ho trovato maggiori dettagli su come farlo qui rossp.org/blog/2006/jul/11/sending-e-mails-templates
mpen

1
Per commentare le domande, si desidera utilizzare i commenti, non le risposte.
Suriv

2

Oltre al modo dizionario, può essere utile conoscere il seguente formato:

print '<a href="%s">%s</a>' % (my_url, my_url)

Qui è un po 'ridondante e il modo in cui il dizionario è certamente meno soggetto a errori quando si modifica il codice, ma è ancora possibile usare le tuple per inserimenti multipli. Il primo %sviene sostituito con il primo elemento nella tupla, il secondo %sviene sostituito con il secondo elemento nella tupla e così via per ogni elemento nella tupla.


Ho appena detto a un ragazzo di averlo suggerito :) Ha cancellato il suo post. Mi sento un po 'male adesso. Sì, sono consapevole di poterlo fare, ma non era proprio quello che cercavo. Come hai detto, è ridondante ed my_urlè in realtà una chiamata di funzione che non voglio essere valutata due volte. Due volte non è poi così male, ma avrebbe potuto essere facilmente 20 volte :)
mpen

5
Ho pensato di mantenere il mio, nel caso in cui aiuti qualcun altro. Bene, il modo in cui il dizionario è probabilmente il modo migliore per andare. Ma per ridondanza, (get_my_url(), )*20chiama la funzione una sola volta e la duplica 20 volte.
Ponkadoodle,
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.