I have some data objects on which I want to implement a strong and equals functions that go in-depth.
I implemented str and eq and although equality works fine I cannot make str behave in the same way:
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__
When I run:
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)
I get:
{'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
since t1 and t2 contain the same values the equals return true (as expected) while since t3 contains a different value in the list the result is false (also as expected). What I would like is to have the same behaviour for the to string (basically to also go in-depth also for the elements in the list (or set or dict ...).
For print(t1) I would like to obtain something like:
{'attr2': ["{'attr2': 'same', 'attr1': 'bean 1.1'}", "{'attr2': 42, 'attr1': 'bean 1.2'}"], 'attr1': 'bean 1'}
which is actually obtained if I do:
Bean("bean 1", [Bean("bean 1.1", "same").__str__(), Bean("bean 1.2", 42).__str__()]).__str__
Since I do not know the types of the attributes attr1, attr2 in my Bean objects (they may be listed but also sets, dictionaries etc.) is would be nice to have a simple and elegant solution that would not require type checking ...
Is this possible?