5.6. Formattazione di stringhe basata su dizionario

La formattazione di stringhe permette di inserire facilmente dei valori all'interno delle stringhe. I valori sono elencati in una tupla ed inseriti ordinatamente nella stringa al posto dei vari marcatori per la formattazione. Per quanto questo approccio sia efficiente, non rende il codice molto semplice da leggere, specialmente se si stanno inserendo molti valori. Non potete semplicemente scorrere la stringa in un passaggio e capire quale sarà il risultato; dovete continuamente passare dalla stringa alla tupla di valori.

Esiste una forma alternativa per la formattazione di stringhe che usa i dizionari al posto delle tuple di valori.

Esempio 5.13. Introduzione alla formattazione di stringhe basata su dizionario

>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
>>> "%(pwd)s" % params                                    1
'secret'
>>> "%(pwd)s is not a good password for %(uid)s" % params 2
'secret is not a good password for sa'
>>> "%(database)s of mind, %(database)s of body" % params 3
'master of mind, master of body'
1 Al posto di una tupla di valori espliciti, questo metodo di formattazione usa un dizionario, params. Ed al posto di un semplice marcatore %s nella stringa, il marcatore contiene un nome tra parentesi. Questo nome è usato come una chiave nel dizionario params e ne sostituisce il corrispondente valore, secret, al posto del marcatore %(pwd)s.
2 La formattazione di stringhe basata su dizionario funziona con qualsiasi numero di chiavi. Ogni chiave deve esistere nel dizionario, o la formattazione fallirà con un KeyError.
3 Potete specificare la stessa chiave due volte, ogni occorrenza verrà rimpiazzata con il medesimo valore.

Quindi perché dovreste usare la formattazione basata su dizionario? Beh, sembra una perdita di tempo impostare un dizionario solo per formattare una stringa nella riga successiva; è davvero molto più utile quando già avete un dizionario significativo. Come locals.

Esempio 5.14. Formattazione di stringhe basata su dizionario in BaseHTMLProcessor.py

    def handle_comment(self, text):        
        self.pieces.append("<!--%(text)s-->" % locals()) 1
1 L'utilizzo della funzione built-in locals è il metodo più comune di utilizzo della formattazione di stringhe basata su dizionario. Significa che potete usare i nomi di variabili locali all'interno della vostra stringa (in questo caso, text, che è stato passato al metodo della classe come argomento) ed ogni variabile menzionata sarà sostituita con il suo valore. Se text è 'Begin page footer', la formattazione della stringa "<!--%(text)s-->" % locals() porterà alla stringa '<!--Begin page footer-->'.
    def unknown_starttag(self, tag, attrs):
        strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs]) 1
        self.pieces.append("<%(tag)s%(strattrs)s>" % locals())                              2
1 Quando questo metodo è chiamato, attrs è una lista di tuple chiave/valore, come gli items di un dizionario, il che vuol dire che possiamo usare un assegnamento multi-variabile per scorrerlo. Dovrebbe essere un meccanismo familiare oramai, ma ci sono molte cose da evidenziare, quindi analizziamole singolarmente:
  1. Supponiamo che attrs sia [('href', 'index.html'), ('title', 'Go to home page')].
  2. Nel primo giro di list comprehension, key avrà valore 'href' e value avrà valore 'index.html'.
  3. La formattazione della stringa ' %s="%s"' % (key, value) si risolverà in ' href="index.html"'. Questa stringa diventa il primo elemento della lista ottenuta dalla list comprehension.
  4. Al secondo giro, key avrà valore 'title' e value avrà valore 'Go to home page'.
  5. La formattazione della stringa si risolverà in ' title="Go to home page"'.
  6. La list comprehension ritorna una lista di queste due stringhe, e strattrs le concatenerà assieme per formare ' href="index.html" title="Go to home page"'.
2 Ora, usando una formattazione di stringhe basata su dizionario, inseriamo il valore di tag e strattrs nella stringa. Così, se tag è 'a', il risultato finale è '<a href="index.html" title="Go to home page">', ed è ciò che viene aggiunto a self.pieces.
Importante
Usare una formattazione di stringhe basata su dizionari con locals è un modo conveniente per ottenere una formattazione di stringhe complessa in maniera più leggibile, ma ha un prezzo. C'è una minima perdita di performance nell'effettuare una chiamata a locals, in quanto locals costruisce una copia dello spazio dei nomi locale.