string — Constantes de texto y plantillas

Propósito:Contiene constantes y clases para trabajar con texto.

El módulo string data de las primeras versiones de Python. Muchas de las funciones implementadas previamente en este módulo se han movido a métodos de objetos str. El módulo string conserva varias constantes útiles y clases para trabajar con objetos str. Esta discusión se concentrará en ellos.

Funciones

La función capwords() capitaliza todas las palabras de una cadena.

string_capwords.py
import string

s = 'The quick brown fox jumped over the lazy dog.'

print(s)
print(string.capwords(s))

Los resultados son los mismos que se obtienen al invocar split(), capitalizando las palabras en la lista resultante, y luego invocar join() para combinar los resultados.

$ python3 string_capwords.py

The quick brown fox jumped over the lazy dog.
The Quick Brown Fox Jumped Over The Lazy Dog.

Plantillas

Las plantillas de cadenas se agregaron como parte de PEP 292 y son una alternativa a la sintaxis de interpolación incorporada. Con la interpolación string.Template, las variables son identificadas al anteponer el nombre con $ `` (por ejemplo, ``$var). Alternativamente, si es necesario para separarlas del texto circundante, también pueden ser envueltas con llaves (por ejemplo, ${var}).

Este ejemplo compara una plantilla simple con una cadena similar de interpolación usando el operador % y la nueva sintaxis de formateo de cadena usando str.format().

string_template.py
import string

values = {'var': 'foo'}

t = string.Template("""
Variable        : $var
Escape          : $$
Variable in text: ${var}iable
""")

print('TEMPLATE:', t.substitute(values))

s = """
Variable        : %(var)s
Escape          : %%
Variable in text: %(var)siable
"""

print('INTERPOLATION:', s % values)

s = """
Variable        : {var}
Escape          : {{}}
Variable in text: {var}iable
"""

print('FORMAT:', s.format(**values))

En los primeros dos casos, el carácter desencadenante ($ o %) es escapado repitiendolo dos veces. Para la sintaxis de formateo, tanto { como } necesitan que se escape al repetirlos.

$ python3 string_template.py

TEMPLATE:
Variable        : foo
Escape          : $
Variable in text: fooiable

INTERPOLATION:
Variable        : foo
Escape          : %
Variable in text: fooiable

FORMAT:
Variable        : foo
Escape          : {}
Variable in text: fooiable

Una diferencia clave entre las plantillas y la interpolación de cadenas o formateo es que el tipo de los argumentos no se toma encuenta. Los valores se convierten en cadenas y las cadenas son insertadas en el resultado. No hay opciones de formateo disponibles. Por ejemplo, no hay forma de controlar la cantidad de dígitos utilizados para representar un valor de coma flotante

Un beneficio, sin embargo, es que el uso del método safe_substitute() permite evitar excepciones si no todos los valores requeridos por la plantilla se proporcionan como argumentos.

string_template_missing.py
import string

values = {'var': 'foo'}

t = string.Template("$var is here but $missing is not provided")

try:
    print('substitute()     :', t.substitute(values))
except KeyError as err:
    print('ERROR:', str(err))

print('safe_substitute():', t.safe_substitute(values))

Dado que no hay ningún valor para missing en el diccionario de valores, KeyError es lanzado por substitute (). En lugar de levantar el error, safe_substitute() lo atrapa y deja la expresión variable sola en el texto.

$ python3 string_template_missing.py

ERROR: 'missing'
safe_substitute(): foo is here but $missing is not provided

Plantillas avanzadas

La sintaxis por defecto para string.Template puede ser modificada ajustando los patrones de expresiones regulares que usa para encontrar los nombres de variable en el cuerpo de la plantilla. Una manera simple de hacerlo es cambiar los atributos de clase delimiter y idpattern.

string_template_advanced.py
import string


class MyTemplate(string.Template):
    delimiter = '%'
    idpattern = '[a-z]+_[a-z]+'


template_text = '''
  Delimiter : %%
  Replaced  : %with_underscore
  Ignored   : %notunderscored
'''

d = {
    'with_underscore': 'replaced',
    'notunderscored': 'not replaced',
}

t = MyTemplate(template_text)
print('Modified ID pattern:')
print(t.safe_substitute(d))

En este ejemplo, las reglas de sustitución se cambian para que el delimitador sea % en lugar de $ y los nombres de las variables deben incluir un guión bajo en algún lugar en el medio. El patrón %notunderscored no se reemplaza por nada, porque no incluye un guion bajo.

$ python3 string_template_advanced.py

Modified ID pattern:

  Delimiter : %
  Replaced  : replaced
  Ignored   : %notunderscored

Para cambios aún más complejos, es posible invalidar el atributo pattern y definir una expresión regular completamente nueva. El patrón proporcionado debe contener cuatro grupos nombrados para capturar el delimitador escapado, la variable nombrada, una versión reforzada del nombre de la variable y patrones invalidos del delimitador.

string_template_defaultpattern.py
import string

t = string.Template('$var')
print(t.pattern.pattern)

El valor de t.pattern es una expresión regular compilada, pero la cadena original está disponible a través de su atributo pattern.

\$(?:
  (?P<escaped>\$) |                # dos delimitadores
  (?P<named>[_a-z][_a-z0-9]*)    | # identificador
  {(?P<braced>[_a-z][_a-z0-9]*)} | # identificador reforzado
  (?P<invalid>)                    # expresiones delimitadoras mal formadas
)

Este ejemplo define un nuevo patrón para crear un nuevo tipo de plantilla, usando {{var}} como la sintaxis de la variable.

string_template_newsyntax.py
import re
import string


class MyTemplate(string.Template):
    delimiter = '{{'
    pattern = r'''
    \{\{(?:
    (?P<escaped>\{\{)|
    (?P<named>[_a-z][_a-z0-9]*)\}\}|
    (?P<braced>[_a-z][_a-z0-9]*)\}\}|
    (?P<invalid>)
    )
    '''


t = MyTemplate('''
{{{{
{{var}}
''')

print('MATCHES:', t.pattern.findall(t.template))
print('SUBSTITUTED:', t.safe_substitute(var='replacement'))

Deben proporcionarse ambos patrones named y braced por separado, a pesar de que son lo mismo. Ejecutando el programa de muestra genera el siguiente resultado:

$ python3 string_template_newsyntax.py

MATCHES: [('{{', '', '', ''), ('', 'var', '', '')]
SUBSTITUTED:
{{
replacement

Formateador

La clase Formatter implementa el mismo idioma de especificación de diseño que el método format() de str. Sus características incluyen referencias de tipo coerción, alineación, atributos y campos, argumentos de plantilla nombrados y posicionales, y opcines de formato específico de tipo. La mayoría de las veces el método format() es una interfaz conveniente para estas características, pero Formatter es proporcionado como una forma de crear subclases, para casos donde las variaciones son necesarias.

Constantes

El módulo string incluye varias constantes relacionadas con ASCII y conjuntos de caracteres numéricos.

string_constants.py
import inspect
import string


def is_str(value):
    return isinstance(value, str)


for name, value in inspect.getmembers(string, is_str):
    if name.startswith('_'):
        continue
    print('%s=%r\n' % (name, value))

Estas constantes son útiles cuando se trabaja con datos ASCII, pero dado que cada vez es más común encontrar texto no ASCII en alguna forma de Unicode, su aplicación es limitada.

$ python3 string_constants.py

ascii_letters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW
XYZ'

ascii_lowercase='abcdefghijklmnopqrstuvwxyz'

ascii_uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

digits='0123456789'

hexdigits='0123456789abcdefABCDEF'

octdigits='01234567'

printable='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ
RSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

punctuation='!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

whitespace=' \t\n\r\x0b\x0c'

Ver también