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

```Python
price = 69.42
message = "The total price is" + price + "EUR"
```

Purtroppo, 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()*:

```Python
message = "The total price is" + str(price) + "EUR"
```

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

1. Con l’operatore Modulo
2. Con il metodo *str.format()*
3. Con interpolazione delle stringhe
4. Con stringhe template

### Operatore Modulo

La **più vecchia formattazione delle stringhe integrata in Python** utilizza l’[operatore Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/operatori-python/ "Operatori 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.

<table>
  <thead>
    <tr>
      <th><strong>Componente</strong></th>
      <th><strong>Nome</strong></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Modello con segnaposto/i</td>
      <td>template</td>
    </tr>
    <tr>
      <td>Operatore Modulo</td>
      <td>%</td>
    </tr>
    <tr>
      <td>Dati da inserire</td>
      <td>data</td>
    </tr>
    <tr>
      <td>Stringa formattata</td>
      <td>message</td>
    </tr>
  </tbody>
</table>

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

```Python
template = "The total price is %s"
```

**Definiamo quindi il valore da inserire** sotto forma di variabile con il nome *data*:

```Python
data = 69.51
```

Per **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*:

```Python
message = template % data
```

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

```Python
message = "Here comes %s" % "Jack"
```

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

```Python
prices = (42, 69, 51)
message = "The total price is %s" % sum(prices)
```

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

```Python
from math import pi as PI
print("The value of Pi is approximately %s" % PI)
```

Se invece come segnaposto utilizziamo l’abbreviazione *%g*, sono visualizzate solo cinque cifre decimali:

```Python
print("The value of Pi is approximately %g" % PI)
```

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

```Python
person = ('John', 42)
message = "My friend %s is %s years old" % person
```

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

```Python
person = {'name': 'John', 'age': 42}
message = "My friend %(name)s is %(age)s years old" % person
```

### Metodo *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](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/split-in-python/ "split in 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:

```Python
template = "Here comes {}"
data = 'Jack'
message = template.format(data)
```

Se la **stringa template contiene più segnaposti**, passiamo di conseguenza molti argomenti:

```Python
message = "My friend {} is {} years old".format('John', 42)
```

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

```Python
message = "My friend {1} is {0} years old".format(69, 'Jim')
```

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

```Python
person = ('John', 42)
message = "My friend {} is {} years old".format(*person)
```

Nelle stringhe più lunghe, i segnaposti che non dicono nulla aumentano velocemente la confusione. È meglio utilizzare **argomenti denominati**:

```Python
template = "My friend {name} is {age} years old"
message = template.format(name = 'Jack', age = 51)
```

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

```Python
# define dict
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)
```

Una 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**:

```Python
samples = [('A0147D', 27.6), ('X1489M', -4.7), ('P9921U', -10.93)]
for sample in samples:
    print('| {} | {} |'.format(*sample))
```

L’output risulta disallineato perché i numeri sono di lunghezza diversa:

```Bash
| A0147D | 27.6 |
| X1489M | -4.7 |
| P9921U | -10.93 |
```

Adattiamo il codice e **definiamo una serie di opzioni di formattazione**:

```Python
for sample in samples:
    print('| {} | {: 6.2f} |'.format(*sample))
```

Ora l’output è corretto:

```Bash
| A0147D | 27.60 |
| X1489M | -4.70 |
| P9921U | -10.93 |
```

Analizziamo più da vicino le **opzioni di formattazione del secondo segnaposto**. Sono inserite dopo i due punti e comprendono quattro componenti:

1. Spazio: mette uno spazio davanti ai numeri positivi per compensare il posto occupato dal segno meno dei numeri negativi.
2. Numero prima del punto: numero delle lettere disponibili complessivamente per il numero.
3. Numero dopo il punto: numero di cifre decimali, eventualmente riempito con zeri.
4. 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](https://docs.python.org/3/library/string.html#format-string-syntax "Documentazione di 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](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/f-string-in-python/), questi vengono riempiti immediatamente:

```Python
message = f"40 + 2 equals {40 + 2}"
```

L’espressione può anche essere il nome di una variabile:

```Python
name = 'Jack'
message = f"Here comes {name}"
```

È possibile integrare senza problemi diverse espressioni:

```Python
prices = (42, 69, 51)
currency = 'EUR'
message = f"The total price is {sum(prices)} {currency}"
```

### Stringhe 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()*:

```Python
# 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')
```

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

```Python
template = Template("Let's buy $amount ${fruit}s")
message = template.substitute(amount = 3, fruit = 'orange')
```

## Quale metodo scegliere per la formattazione delle stringhe in Python?

I singoli metodi presentano proprietà specifiche che riepiloghiamo qui:

<table>
  <thead>
    <tr>
      <th><strong>Metodo</strong></th>
      <th><strong>Schema</strong></th>
      <th><strong>Segnaposto</strong></th>
      <th><strong>Vantaggi</strong></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Formattazione Modulo</td>
      <td>template % data</td>
      <td>%, %(key)</td>
      <td>In Python versione &lt; 2.6</td>
    </tr>
    <tr>
      <td>str.format()</td>
      <td>template.format(data)</td>
      <td>{}, {index}, {key}</td>
      <td>Per formattazioni complesse</td>
    </tr>
    <tr>
      <td>f-string</td>
      <td>f“{expression}“</td>
      <td>{expression}</td>
      <td>Per molte stringhe</td>
    </tr>
    <tr>
      <td>Stringa template</td>
      <td>template.substitute(data)</td>
      <td>${identifier}</td>
      <td>Se le stringhe sono originate dall’utente</td>
    </tr>
  </tbody>
</table>


This is a markdown version of: [https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/formattazione-delle-stringhe-in-python/](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/formattazione-delle-stringhe-in-python/) for AI/LLM consumption.