Al escribir una clase recientemente, inicialmente incluía un método __repr__
lo largo de las siguientes líneas:Incluyendo un formato iterable como parte de una cadena con formato grande
return "{}({!r}, {!r}, {!r})".format(
self.__class__.__name__,
self.arg1,
self.arg2,
self.arg3)
Repitiendo el '{r!}' Fragmento de código como el que se siente mal y sería tedioso mantener si agrego más argumentos a esta clase. Sin embargo, las alternativas más robustas que se me ocurrieron no van a ganar ningún premio por elegancia tampoco.
La construcción de la cadena de formato mediante programación:
fmt = "{}(%s)" % ", ".join(["{!r}"]*3)
return fmt.format(self.__class__.__name__,
self.arg1,
self.arg2,
self.arg3)
formato a los argumentos por separado con str.join
:
args = ", ".join(map(repr, [self.arg1, self.arg2, self.arg3]))
return "{}({})".format(self.__class__.__name__, args)
he implementado actualmente la clase utilizando el ejemplo anterior, pero estoy interesado en sugerencias para enfoques alternativos (ya que no estoy particularmente contento con ninguna de las opciones anteriores).
Actualización: Inspirado por la respuesta de Ned, he ahora añade la siguiente función de utilidad a un módulo de ayuda:
def format_iter(iterable, fmt='{!r}', sep=', '):
return sep.join(fmt.format(x) for x in iterable)
>>> format_iter(range(10))
'0, 1, 2, 3, 4, 5, 6, 7, 8, 9'
>>> format_iter(range(10), sep='|')
'0|1|2|3|4|5|6|7|8|9'
>>> format_iter(range(10), fmt='{:04b}', sep='|')
'0000|0001|0010|0011|0100|0101|0110|0111|1000|1001'
>>> format_iter(range(10), fmt='{0.real}+{0.imag}j')
'0+0j, 1+0j, 2+0j, 3+0j, 4+0j, 5+0j, 6+0j, 7+0j, 8+0j, 9+0j'
Update2: Terminé la adición de una segunda función de utilidad, casi idéntica a la de la respuesta de AGF:
def call_repr(name, *args):
return "{}({})".format(name, format_iter(args))
Así que la función __repr__
originalmente ofender ahora queda como:
def __repr__(self):
return call_repr(self.__class__.__name__,
self.arg1,
self.arg2)
(Sí, uno de los argumentos de constructor originales se fueron el día de hoy.)
Al final resultó que, terminé haciendo esto, solo con una llamada '' format_iter (args) '' en lugar del Inv en línea ocación de '' str.join'' – ncoghlan