Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: how to recursively apply __str__ in print

Tags:

python

I had some problem printing user-defined class instance in containers. In short, if my code is:

class A():
    def __str__(self):
        return 'abc'

class B():
    def __str__(self):
        return str(A())

a,b=A(),B()
C=[[a],b]
print(C)

Then the output should be like:[[<__main__.A object at 0x02D99910>], <__main__.B object at 0x02DD5030>], but I want it to recursively apply customized __str__ and works even in nested lists or classes, i.e. I want the output to be [['abc'],'abc']. Any pythonic way to do?

like image 221
YiFei Avatar asked Feb 01 '16 01:02

YiFei


2 Answers

@Blckknight should have submitted as an answer, because that seems to be the correct answer (it worked for my very similar question):

**override repr() instead of str()

def __repr__(self):
    return "abc"

you can also add this for completeness def str(self): return self.repr()

@Blckknight if you want to resubmit as an answer for the points, you should. I wish I could just add a comment but i don't have the reputation to do that.

like image 65
cperlmutter Avatar answered Sep 22 '22 09:09

cperlmutter


You would need to override the __str__ method of list, not A or B, since that's where the recursion needs to begin. That is, to turn a list into a string, you need to recursively turn each object in the list into a string. Unfortunately, you cannot do that. The best you can do is write a separate function, something like

def list_to_str(l):
    if isinstance(l, list):
        return "[%s]" % (", ".join(map(list_to_str, l)),)
    else:
        return "'%s'" % (str(l),)

print(list_to_str(C))
like image 25
chepner Avatar answered Sep 21 '22 09:09

chepner