Tengo unos objetos de datos sobre los que quiero implementar unas funciones to string y equals que profundicen.
He implementado str y eq y aunque la igualdad funciona bien no consigo que str se comporte de la misma manera:
class Bean(object):
def __init__(self, attr1, attr2):
self.attr1 = attr1
self.attr2 = attr2
def __str__(self):
return str(self.__dict__)
def __eq__(self, other):
return self.__dict__ == other.__dict__
Cuando ejecuto
t1 = Bean("bean 1", [Bean("bean 1.1", "same"), Bean("bean 1.2", 42)])
t2 = Bean("bean 1", [Bean("bean 1.1", "same"), Bean("bean 1.2", 42)])
t3 = Bean("bean 1", [Bean("bean 1.1", "different"), Bean("bean 1.2", 42)])
print(t1)
print(t2)
print(t3)
print(t1 == t2)
print(t1 == t3)
Me sale:
{'attr2': [<__main__.Bean object at 0x7fc092030f28>, <__main__.Bean object at 0x7fc092030f60>], 'attr1': 'bean 1'}
{'attr2': [<__main__.Bean object at 0x7fc091faa588>, <__main__.Bean object at 0x7fc092045128>], 'attr1': 'bean 1'}
{'attr2': [<__main__.Bean object at 0x7fc0920355c0>, <__main__.Bean object at 0x7fc092035668>], 'attr1': 'bean 1'}
True
False
como t1 y t2 contienen los mismos valores los equals devuelven true (como era de esperar) mientras que como t3 contiene un valor diferente en la lista el resultado es false (también como era de esperar). Lo que me gustaría es tener el mismo comportamiento para la cadena to (básicamente para profundizar también en los elementos de la lista (o set o dict ...).
Para print(t1) me gustaría obtener algo como:
{'attr2': ["{'attr2': 'same', 'attr1': 'bean 1.1'}", "{'attr2': 42, 'attr1': 'bean 1.2'}"], 'attr1': 'bean 1'}
que en realidad se obtiene si hago
Bean("bean 1", [Bean("bean 1.1", "same").__str__(), Bean("bean 1.2", 42).__str__()]).__str__
Como no conozco los tipos de los atributos attr1, attr2 en mis objetos Bean (pueden ser listas pero también conjuntos, diccionarios, etc.) estaría bien tener una solución simple y elegante que no requiriera comprobación de tipos ...
¿Es posible?
Puedes usar __repr__
en lugar de __str__
, que funciona recursivamente, aunque no es una buena idea la mayoría de las veces (mira esta respuesta para más detalles). Sin embargo, esto funciona para mí:
def __repr__(self):
return str(self.__dict__)
Puede intentar utilizar repr en lugar de str.
Obtuve la siguiente salida para print(t1), al usar def repr(self): en lugar de str.
{'attr1': 'bean 1', 'attr2': [{'attr1': 'bean 1.1', 'attr2': 'same'}, {'attr1': 'bean 1.2', 'attr2': 42}]}
Hazme saber si esto resuelve tu problema. Adjunto imagen como referencia.
Saludos, Vinith