8.6. Cadenas de formato basadas en diccionarios

¿Por qué le he enseñado que existen locals y globals? Para que pueda aprender a dar formato a cadenas usando diccionarios. Como recordará, la cadena de formato normal proporciona una manera sencilla de insertar valores en cadenas. Los valores se listan en una tupla y se insertan por orden en la cadena en lugar de cada marcador de formato. Aunque esto es eficiente, no siempre produce el código más fácil de leer, especialmente cuando ha de insertar múltiples valores. No se puede simplemente echar un vistazo a la cadena y comprender cual será el resultado; alternará constantemente entre leer la cadena y la tupla de valores.

Hay una forma alternativa de dar formato a cadenas que usa diccionarios en lugar de tuplas de valores.

Ejemplo 8.13. Presentación de la cadena de formato basada en diccionarios

>>> 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 En lugar de una tupla de valores explícitos, esta forma de cadena de formato utiliza un diccionario, params. Y en lugar de un ser un simple %s en la cadena, el marcador contendrá un nombre entre paréntesis. Este nombre se utilizar como clave para acceder al diccionario params y se inserta el valor correspondiente, secret, en lugar del marcador %(pwd)s.
2 La cadena de formato con diccionarios funciona con cualquier cantidad de claves por nombre. Cada clave debe existir en el diccionario dado, o el formato fallará con una KeyError.
3 Incluso puede especificar la misma clave dos veces; cada una será sustituida por el mismo valor.

Así que, ¿por qué usar una cadena de formato con diccionario? Bien, parece matar moscas a cañonazos construir un diccionario de claves y valores sólo para dar formato a una cadena en la siguiente línea; es mucho más útil cuando resulta que ya tiene un diccionario lleno de claves significativas con sus respectivos valores. Como locals.

Ejemplo 8.14. Formato basado en diccionarios en BaseHTMLProcessor.py

    def handle_comment(self, text):        
        self.pieces.append("<!--%(text)s-->" % locals()) 1
1 El uso más común de la cadena de formato con diccionarios es acompañarla de la función incorporada locals. Significa que puede usar los nombres de las variables locales dentro de la cadena (en este caso, text, que se le pasó al método de la clase como argumento) y cada variable nombrada será sustituida por su valor. Si text es 'Begin page footer', el formato "<!--%(text)s-->" % locals() producirá la cadena '<!--Begin page footer-->'.

Ejemplo 8.15. Más cadenas de formato basadas en diccionarios

    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 Cuando se invoca este método, attrs es una lista de tuplas clave/valor igual que los items de un diccionario, lo que significa que puede usar la asignación multivariable para iterar sobre ella. Este patrón debería resultarle familiar ya, pero se está haciendo mucho aquí, así que vamos a hacer una disección:
  1. Suponga que attrs es [('href', 'index.html'), ('title', 'Go to home page')].
  2. En la primera iteración de la lista por comprensión, key tendrá 'href' y value tendrá 'index.html'.
  3. La cadena de formato ' %s="%s"' % (key, value) producirá ' href="index.html"'. Esta cadena se convierte en el primer elemento del valor devuelto por la lista por comprensión.
  4. En la segunda iteración, key tendrá 'title', y value tendrá 'Go to home page'.
  5. La cadena de formato producirá ' title="Go to home page"'.
  6. La lista por comprensión devuelve una lista con estas dos cadenas producto, y strattrs juntará ambos elementos de esta lista para formar ' href="index.html" title="Go to home page"'.
2 Ahora insertará el valor de tag y strattrs en una cadena usando la cadena de formato basada en diccionarios. De manera que si tag es 'a', el resultado final será '<a href="index.html" title="Go to home page">', y eso es lo que se agrega a self.pieces.
importante
Usar cadenas de formato basadas en diccionarios con locals es una manera conveniente de hacer más legibles expresiones de cadenas de formato, pero tiene un precio. Llamar a locals tiene una ligera influencia en el rendimiento, ya que locals construye una copia del espacio de nombres local.