Search code examples
pythonpython-3.xooprepr

How to partially overwrite __repr__ for a class in python?


I'm learning Python and it's my first question here :)

So I am defining a class:

class Nr_Heap:
    def __init__(self):
        self._top = None          #a queue() of Point()
        self._tmp_bottom = None   #a Point()

    def __str__(self):
        if self._top != None:
            if self.top:
                return f"Nr Heap of [{', '.join([f'{str(self.top[i])}' for i in range(len(self.top))])}]"
            else:
                return f"Nr Heap of [...empty...]"
        else:
            return f"Nr Heap (not used)"

The __str__ method seems to be doing what I want it to do, but I'm wandering, is it possible to write a __repr__ method, so that it would partially overwrite the default __repr__, that is only in case, when my __str__ is returning f"Nr Heap [{', '.join([f'{str(self.top[i])}' for i in range(len(self.top))])}]"?

Let me show it on example. When I initiate the Nr_Heap() object, the output is:

str(nh):  Nr Heap (not used)
repr(nh):  <conflicts.Nr_Heap object at 0x7f2e02d1bfd0>

Then I set Nr_Heap .top to be an empty collections.deque() and I get:

str(nh):  Nr Heap of [...empty...]
repr(nh):  <conflicts.Nr_Heap object at 0x7f2e02d1bfd0>

And lastly, after adding 3 points to the queue:

str(nh):  Nr Heap of [Point: 3(3, 3), Point: 2(2, 2), Point: 1(1, 1)]
repr(nh):  <conflicts.Nr_Heap object at 0x7f2e02d1bfd0>

and only in the last case I want a __repr__ method to return something like this:

<conflicts.Nr_Heap object: [Point: 3(3, 3), Point: 2(2, 2), Point: 1(1, 1)]>

How to do that?


Solution

  • If I understand you correctly, something like the following should be possible:

    def __repr__(self):
        if str(self) == "some fixed string"
            return super().__repr__()
        return "some other repr string"
    

    or whatever you're preferred if-condition is (if self.top may be another option).

    The key is to use super().__repr__() to return the default repr result. That default will take into account the current class, so it behaves as if you hadn't implemented __repr__ at all.