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.