6

Situation: I'm new to python and currently trying to learn the ropes, I've attempted creating a linked list class to assist in getting a better understanding of the language and its structures. I know that the __repr__ function is basically supposed to return the same thing as __str__ but I'm unsure on what the actual difference is.

Here's my class so far:

class LinkedList:
    class Node:
        def __init__(self, val, prior=None, next=None):
            self.val = val
            self.prior = prior
            self.next  = next

    def __init__(self):
        self.head = LinkedList.Node(None) 
        self.head.prior = self.head.next = self.head 
        self.length = 0

    def __str__(self):
        """Implements `str(self)`. Returns '[]' if the list is empty, else
        returns `str(x)` for all values `x` in this list, separated by commas
        and enclosed by square brackets. E.g., for a list containing values
        1, 2 and 3, returns '[1, 2, 3]'."""
        if len(self)==0:
            return '[]'
        else:
            return '[' +  ', '.join(str(x) for x in self) + ']'

    def __repr__(self):
        """Supports REPL inspection. (Same behavior as `str`.)"""
        return '[' +  ', '.join(str(x) for x in self) + ']'

When I test this code against the below code, I'll get an error basically saying the blank string '[]' isn't actually being returned when using the repr function. How could I edit this methods body to fix this issue? I've also tried return str(self) and I'm not sure why that won't work either.

from unittest import TestCase
tc = TestCase()

lst = LinkedList()
tc.assertEqual('[]', str(lst))
tc.assertEqual('[]', repr(lst))

lst.append(1)
tc.assertEqual('[1]', str(lst))
tc.assertEqual('[1]', repr(lst))
  • 5
    *"I know that the `__repr__` function is basically supposed to return the same thing as `__str__`"* - I'm not sure how you know that, but that's not right, see the docs on [`__str__`](https://docs.python.org/3/reference/datamodel.html#object.__str__) and [`__repr__`](https://docs.python.org/3/reference/datamodel.html#object.__repr__). – jonrsharpe Jun 12 '16 at 21:13
  • The code you've shown can't be run as written (you've left out the `__len__` and `__iter__` methods, at least), which makes troubleshooting it very difficult. While we appreciate a concise question, we need a [MCVE] that actually works! – Blckknght Jun 13 '16 at 00:34
  • This has all the answers: [Difference between __str__ and __repr__?](https://stackoverflow.com/q/1436703) – djvg Dec 04 '20 at 09:38

1 Answers1

8

The __repr__ function returns a string representation of a Python object that may be evaluated by the Python interpreter to instantiate another instance of the object. So if you had a list:

x = ['foo', 'bar']

Its __repr__ string would be:

x_str = repr(x)
print(x_str)
>>>>
"['foo', 'bar']"

And you could do:

x2 = eval(x_str)
print(type(x2))
>>>>
<class 'list'>

It's a way to get a string representation of a Python object that can be converted back into a new instance of said object.

Basically the difference between __str__ and __repr__ is that the former returns a string representation of the object meant to be read by a person and the latter returns a string representation of the object meant to be parsed by the Python interpreter. Be very careful with this!

In your example code, it appears that __str__ and __repr__ return the same string representation. That's fine. However, if you wanted, you could make your __str__ return some prettier formatted version (for instance with carriage returns and no brackets), but __repr__ should always return a string that could be parsed by the Python interpreter to reconstruct the object.

Trekkie
  • 964
  • 1
  • 9
  • 32
  • 1
    This is a great way to think about repr! I was wondering how I should structure my output and this answers it great. However, it should be noted that repr and eval should not be used as a serializer because there are instances where this is broken. But this is a great standard for creating repr's. – Addison Apr 27 '18 at 12:56