Reputation: 1545
I have a class that functions similarly to a list. It can contain itself and that leads to issues printing. Python handles this with replacing the recursive part with Ellipsis. I can do that when the nesting is simple where a = []; a.append(a)
by comparing individual items with self, but when there are more complicated relationships this doesn't work. What is a good way to replace recursive parts with Ellipsis or hijack pythons printing mechanism? I tried to construct a list out of the values from self and return str(mylist)
, but I got a Recursion error from that too.
class foo:
def __init__(self):
#stuff happens
def __repr__(self):
s = []
for i in range(self.length):
if self[i] is self:
s.append("[...]")
else:
s.append(repr(self[i]))
return f"[{','.join(s)}]"
class bar:
def __init__(self):
# stuff happens
def __repr__(self):
return str(list(self))
a = foo()
b = foo()
a.append(b)
b.append(a)
print(a)
RecursionError: maximum recursion depth exceeded
a = bar()
b = bar()
a.append(b)
b.append(a)
print(a)
RecursionError: maximum recursion depth exceeded
Upvotes: 3
Views: 172
Reputation: 1545
Using reprlib, recommended by snakecharmerb, I solved the issue with the decorator reprlib.recursive_repr
. The description of that function is:
@reprlib.recursive_repr(fillvalue="...")
Decorator for
__repr__()
methods to detect recursive calls within the same thread. If a recursive call is made, the fillvalue is returned, otherwise, the usual__repr__()
call is made.
I use the fillvalue "[...]"
with brackets because otherwise the result can end up looking like [3, ...]
which is not pretty and not the way python formats lists.
@reprlib.recursive_repr("[...]")
def __repr__(self):
return f"[{','.join(map(repr, self))}]"
Upvotes: 3