Formattazione delle stringhe in Python
Python offre un supporto eccellente per le operazioni sulle stringhe e l’elaborazione del testo. Questo linguaggio prevede svariate opzioni per la formattazione e l’output dei testi. Vi presentiamo i principali metodi di formattazione delle stringhe in Python.
A quale scopo si utilizzano i metodi di formattazione delle stringhe in Python?
Le stringhe sono sequenze di caratteri che in Python possono contenere singole lettere, parole, frasi o anche interi documenti. Nella pratica spesso è necessario usare metodi per la formattazione delle stringhe, con cui non si intendono assolutamente gli elementi visivi come il grassetto in Word. Dunque, di cosa si tratta?
Le stringhe possono essere composte da più pezzi. In molti casi si devono mescolare componenti statici e dati variabili, ad esempio per restituire dati e creare documenti nello sviluppo web.
Prendiamo ad esempio un negozio online. Vogliamo calcolare il prezzo totale dei prodotti nel carrello e mostrarlo all’utente: “Il prezzo totale è di […] euro”. Per prima cosa si può provare a comporre la stringa con l’operatore di concatenazione:
price = 69.42
message = "The total price is" + price + "EUR"
PythonPurtroppo, viene generato un messaggio di errore, perché il prezzo è un numero e non può essere concatenato con una stringa. Dobbiamo quindi prima convertire il numero in una stringa con la funzione str():
message = "The total price is" + str(price) + "EUR"
PythonIn questo modo, il codice diventa velocemente confuso. Sarebbe meglio definire tutto il testo con i segnaposti e poi inserire i dati. Per convertire i dati potrebbe essere necessario adattarne la formattazione. È proprio questo che fanno i metodi di formattazione delle stringhe in Python.
Come funzionano i metodi di formattazione delle stringhe in Python?
Python supporta svariati metodi per la formattazione delle stringhe, ciascuno con i propri vantaggi e svantaggi. Nel tempo il numero di metodi è aumentato, motivo per cui tra loro ci sono molti punti in comune e alcune differenze. Vi presentiamo i principali metodi di formattazione delle stringhe in Python:
- Con l’operatore Modulo
- Con il metodo str.format()
- Con interpolazione delle stringhe
- Con stringhe template
Operatore Modulo
La più vecchia formattazione delle stringhe integrata in Python utilizza l’operatore Python per il segno percentuale, altrimenti utilizzato per l’operazione matematica modulo. Per questo motivo, il metodo è chiamato anche formattazione delle stringhe Modulo.
Di seguito utilizziamo uno schema con tre variabili. I nomi usati sono irrilevanti; li abbiamo scelti per rendere il codice più comprensibile possibile.
Componente | Nome |
---|---|
Modello con segnaposto/i | template |
Operatore Modulo | % |
Dati da inserire | data |
Stringa formattata | message |
Per prima cosa definiamo il modello come variabile di stringa con il nome template. All’interno del modello determiniamo la posizione del segnaposto con l’abbreviazione %s:
template = "The total price is %s"
PythonDefiniamo quindi il valore da inserire sotto forma di variabile con il nome data:
data = 69.51
PythonPer eseguire la formattazione della stringa di Python scriviamo il modello della stringa, seguito dall’operatore Modulo, e poi la variabile data. Allo stesso modo assegniamo la stringa formattata alla variabile message:
message = template % data
PythonI dati possono essere una variabile. Ma possiamo utilizzare anche un letterale o un’espressione. L’operazione Modulo può essere inserita in un’unica riga. Di seguito un esempio di letterale di stringa inserito al posto del segnaposto:
message = "Here comes %s" % "Jack"
PythonUn altro esempio: calcoliamo la somma dei prezzi unitari e inseriamo il prezzo totale nel messaggio. Si applica lo stesso schema. L’operatore Modulo può essere seguito da un’espressione.
prices = (42, 69, 51)
message = "The total price is %s" % sum(prices)
PythonA questo punto forse vi starete chiedendo perché come segnaposto viene usato %s e non semplicemente il segno percentuale. La “s” ha in effetti un significato particolare: al momento dell’inserimento, i dati vengono convertiti in una stringa con la funzione str().
In Python per la formattazione delle stringhe sono previste altre abbreviazioni che ad esempio formattano i numeri in modo speciale. Per spiegarlo, prendiamo come esempio il Pi greco. Inseriamo il numero nell’ormai noto segnaposto %s. L’output contiene 15 cifre decimali:
from math import pi as PI
print("The value of Pi is approximately %s" % PI)
PythonSe invece come segnaposto utilizziamo l’abbreviazione %g, sono visualizzate solo cinque cifre decimali:
print("The value of Pi is approximately %g" % PI)
PythonOltre a %s e %g sono disponibili varie altre opzioni, che potete scoprire nella sezione seguente.
Con la formattazione delle stringhe di Python è anche possibile definire e riempire più segnaposti. In questo caso l’operatore Modulo si aspetta una tupla con tanti valori quanti sono i segnaposti presenti. I segnaposti vengono riempiti con i valori:
person = ('John', 42)
message = "My friend %s is %s years old" % person
PythonCome potete vedere, la formattazione con l’operatore Modulo non risulta di facile lettura. Va un po’ meglio se al posto di una tupla trasmettiamo un dizionario (dict) con i dati. In questo caso inseriamo i nomi delle voci del dizionario tra parentesi dopo il segno percentuale dei segnaposti. Osservando il modello di stringa si vede quali sono i valori previsti:
person = {'name': 'John', 'age': 42}
message = "My friend %(name)s is %(age)s years old" % person
PythonMetodo str.format()
Questo metodo di formattazione delle stringhe di Python è un miglioramento della formattazione Modulo, originariamente contenuta in Python 3 e poi trasferita a Python 2.6. Anziché utilizzare un operatore speciale, si ricorre a un metodo orientato all’oggetto. Così str.format() è coerente con gli altri metodi per le stringhe come la funzione str.split di Python.
Lo schema di base del metodo str.format() di Python somiglia alla formattazione con l’operatore Modulo ed esiste in forma simile anche in .NET e Rust. Come segnaposto nelle stringhe template si usano le parentesi graffe, i dati vengono trasmessi come argomenti della chiamata della funzione:
template = "Here comes {}"
data = 'Jack'
message = template.format(data)
PythonSe la stringa template contiene più segnaposti, passiamo di conseguenza molti argomenti:
message = "My friend {} is {} years old".format('John', 42)
PythonOpzionalmente specifichiamo la posizione degli argomenti da integrare come indice. È così possibile sganciare la sequenza dei segnaposti dagli argomenti. Tenete presente che gli indici iniziano con zero:
message = "My friend {1} is {0} years old".format(69, 'Jim')
PythonSe i singoli valori si trovano in una struttura di dati, utilizziamo l’operatore asterisco prima dell’argomento per decomprimere la struttura di dati. Questa operazione funziona con le liste e le tuple:
person = ('John', 42)
message = "My friend {} is {} years old".format(*person)
PythonNelle stringhe più lunghe, i segnaposti che non dicono nulla aumentano velocemente la confusione. È meglio utilizzare argomenti denominati:
template = "My friend {name} is {age} years old"
message = template.format(name = 'Jack', age = 51)
PythonCon molti valori la lista degli argomenti diventerebbe molto lunga e di conseguenza poco chiara. È quindi meglio raggruppare i valori in un dizionario da decomprimere alla chiamata della funzione. A differenza delle liste e delle tuple, per decomprimere un dizionario utilizziamo un asterisco doppio:
person = {'name': 'Jim', 'age': 69}
# define string with placeholders
template = "My friend {name} is {age} years old"
# unpack dict in `format()` call
message = template.format(**person)
PythonUna particolarità della formattazione delle stringhe in Python con str.format() è rappresentata dalle svariate opzioni di formattazione. Oltre ad ampliare le funzioni della formattazione Modulo, sono particolarmente potenti per l’output del testo nella riga di comando e per i dati tabulari. Di seguito vi presentiamo i meccanismi per la formattazione dei numeri.
Python offre un controllo preciso per restituire numeri sotto forma di testo. Si può così definire come deve essere visualizzato il segno dei numeri. Per i numeri decimali è inoltre possibile determinare il numero di cifre dopo la virgola. È utile per la rappresentazione in tabella di numeri positivi o negativi.
Immaginiamo di voler restituire misurazioni della temperatura:
samples = [('A0147D', 27.6), ('X1489M', -4.7), ('P9921U', -10.93)]
for sample in samples:
print('| {} | {} |'.format(*sample))
PythonL’output risulta disallineato perché i numeri sono di lunghezza diversa:
| A0147D | 27.6 |
| X1489M | -4.7 |
| P9921U | -10.93 |
BashAdattiamo il codice e definiamo una serie di opzioni di formattazione:
for sample in samples:
print('| {} | {: 6.2f} |'.format(*sample))
PythonOra l’output è corretto:
| A0147D | 27.60 |
| X1489M | -4.70 |
| P9921U | -10.93 |
BashAnalizziamo più da vicino le opzioni di formattazione del secondo segnaposto. Sono inserite dopo i due punti e comprendono quattro componenti:
- Spazio: mette uno spazio davanti ai numeri positivi per compensare il posto occupato dal segno meno dei numeri negativi.
- Numero prima del punto: numero delle lettere disponibili complessivamente per il numero.
- Numero dopo il punto: numero di cifre decimali, eventualmente riempito con zeri.
- Lettera “f” prima della parentesi graffa di chiusura: formatta il numero come cifra decimale.
Sono disponibili svariate altre opzioni di formattazione per gestire con precisione l’output di numeri e stringhe. Sono tuttavia usate piuttosto raramente; all’occorrenza consultate la documentazione sulla formattazione delle stringhe in Python.
Interpolazione delle stringhe
A partire da Python 3.6, come metodo di formattazione è disponibile anche l’interpolazione delle stringhe. Questo metodo, noto anche come “f-string”, è il più comodo e il più performante per molte applicazioni. Il nome deriva dalla sintassi generale; queste stringhe iniziano con la lettera “f”, posta subito prima delle virgolette di apertura.
Come segnaposti si usano le parentesi graffe. A differenza dei metodi precedentemente presentati, i segnaposti non contengono l’indice o nomi, ma un’espressione a piacere. Nella definizione delle f-string, questi vengono riempiti immediatamente:
message = f"40 + 2 equals {40 + 2}"
PythonL’espressione può anche essere il nome di una variabile:
name = 'Jack'
message = f"Here comes {name}"
PythonÈ possibile integrare senza problemi diverse espressioni:
prices = (42, 69, 51)
currency = 'EUR'
message = f"The total price is {sum(prices)} {currency}"
PythonStringhe template
Oltre ai tre metodi illustrati, Python supporta anche la formattazione con le stringhe template. Create da una propria classe, proteggono dalle falle di sicurezza generate dall’utente.
Le possibilità di formattazione all’interno delle stringhe template sono limitate. Anziché espressioni a piacere, i segnaposti possono contenere soltanto nomi di variabili. Per via della loro semplicità, le stringhe template sono l’ideale per l’internazionalizzazione delle stringhe in diverse lingue.
Come segnaposto si usa il simbolo del dollaro, seguito dal nome della variabile da inserire. La sintassi delle stringhe template somiglia quindi a quella dei linguaggi shell come Bash o Zsh. Per inserire il valore si richiama il metodo substitute():
# import `Template` class from `string` module
from string import Template
# instantiate template
template = Template("Hey there, I'm $name")
# perform substitution
message = template.substitute(name = 'Jack')
PythonCome nei linguaggi shell, c’è un’altra sintassi per i segnaposti. Il simbolo del dollaro è seguito da parentesi graffe che contengono il nome della variabile. Si possono effettuare sostituzioni all’interno di una parola:
template = Template("Let's buy $amount ${fruit}s")
message = template.substitute(amount = 3, fruit = 'orange')
PythonQuale metodo scegliere per la formattazione delle stringhe in Python?
I singoli metodi presentano proprietà specifiche che riepiloghiamo qui:
Metodo | Schema | Segnaposto | Vantaggi |
---|---|---|---|
Formattazione Modulo | template % data | %, %(key) | In Python versione < 2.6 |
str.format() | template.format(data) | {}, {index}, {key} | Per formattazioni complesse |
f-string | f“{expression}“ | {expression} | Per molte stringhe |
Stringa template | template.substitute(data) | ${identifier} | Se le stringhe sono originate dall’utente |