tutorial examples español ejemplos python string-formatting missing-data

examples - Cómo hacer que Python formatee correctamente el formato Ninguno y los campos no existentes



plot() python (3)

Esta pregunta ya tiene una respuesta aquí:

Si escribo en Python:

data = {''n'': 3, ''k'': 3.141594, ''p'': {''a'': 7, ''b'': 8}} print(''{n}, {k:.2f}, {p[a]}, {p[b]}''.format(**data)) del data[''k''] data[''p''][''b''] = None print(''{n}, {k:.2f}, {p[a]}, {p[b]}''.format(**data))

Yo obtengo:

3, 3.14, 7, 8 Traceback (most recent call last): File "./funky.py", line 186, in <module> print(''{n}, {k:.2f}, {p[a]}, {p[b]}''.format(**data)) KeyError: ''k''

En lugar de un mensaje de error, ¿cómo puedo hacer que Python formatee mejor el formato de los campos Ninguno e inexistente?

Para dar un ejemplo, me gustaría ver en la salida algo más como:

3, 3.14, 7, 8 3, ~, 7, ~

Lo ideal es que, por supuesto, me gustaría poder especificar la cadena utilizada en lugar de los valores que faltan.


El método str.format() no le da un método directo para manejar claves faltantes o reemplazar valores.

Puedes añadir una capa de indirección; pase una asignación que maneje los valores faltantes y None , y modifique el formato para usar solo ese argumento:

class PlaceholderFormatValue(): def __format__(self, spec): return ''~'' def __getitem__(self, name): # handle further nested item access return self class formatting_dict(dict): def __getitem__(self, name): value = self.get(name) if isinstance(value, dict): # rewrap nested dictionaries to handle missing nested keys value = type(self)(value) return value if value is not None else PlaceholderFormatValue() print(''{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}''.format(formatting_dict(data)))

Ahora todas las ranuras se refieren al argumento posicional 0 , que se trata como un diccionario, pero las búsquedas de claves siempre tienen éxito y los valores perdidos y None se reemplazan por un valor de marcador de posición.

Aquí, PlaceholderFormatValue() garantiza que, independientemente de lo que proporcione la especificación de formato, el valor se pueda interpolar en el formato. Esto hace que {0[k]:.2f} funcione, por ejemplo.

Al ajustar cualquier valor de dict y tener acceso de elemento de control PlaceholderFormatValue , lo anterior también puede manejar la falla para proporcionar claves anidadas o diccionarios completos:

>>> data = {''n'': 3, ''k'': 3.141594, ''p'': {''a'': 7, ''b'': 8}} >>> del data[''k''] >>> data[''p''][''b''] = None >>> print(''{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}''.format(formatting_dict(data))) 3, ~, 7, ~ >>> del data[''p''][''a''] >>> print(''{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}''.format(formatting_dict(data))) 3, ~, ~, ~ >>> del data[''p''] >>> print(''{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}''.format(formatting_dict(data))) 3, ~, ~, ~


La recomendación en PEP 3101 es la subclase Formatter :

import string class PartialFormatter(string.Formatter): def __init__(self, missing=''~~'', bad_fmt=''!!''): self.missing, self.bad_fmt=missing, bad_fmt def get_field(self, field_name, args, kwargs): # Handle a key not found try: val=super(PartialFormatter, self).get_field(field_name, args, kwargs) # Python 3, ''super().get_field(field_name, args, kwargs)'' works except (KeyError, AttributeError): val=None,field_name return val def format_field(self, value, spec): # handle an invalid format if value==None: return self.missing try: return super(PartialFormatter, self).format_field(value, spec) except ValueError: if self.bad_fmt is not None: return self.bad_fmt else: raise fmt=PartialFormatter() data = {''n'': 3, ''k'': 3.141594, ''p'': {''a'': ''7'', ''b'': 8}} print(fmt.format(''{n}, {k:.2f}, {p[a]}, {p[b]}'', **data)) # 3, 3.14, 7, 8 del data[''k''] data[''p''][''b''] = None print(fmt.format(''{n}, {k:.2f}, {p[a]:.2f}, {p[b]}'', **data)) # 3, ~~, !!, ~~

Como se configuró, se imprimirá ~~ si no se encuentra un campo o atributo y !! si se usa un formato inválido dado el valor del campo. (Solo use None para el argumento de palabra clave bad_fmt si desea que se bad_fmt el valor predeterminado de un error de valor).

Para manejar las claves faltantes, debe subclasificar tanto get_field para capturar KeyError o AttributeError como format_field para devolver un valor predeterminado para la clave faltante.

Ya que está capturando los errores de format_field , también puede capturar un campo de formato incorrecto capturando el ValueError de la superclase.


Si puede realizar el formateo por separado, puede usar Template.safe_substitute que maneja con gracia los valores faltantes:

>>> from string import Template >>> t = Template("$a $b $c") >>> t.safe_substitute(a=3) ''3 $b $c''