__str__ and __repr__ are used in very similar ways in Python, but they're not interchangeable. __str__ is a built in function used to compute the informal string representations of an object, while __repr__ must be used to compute the official string representations of an object. The visible difference between the informal and official representations has a lot to do with quotation marks. Check out the example below:
y=" 'a string' "
You can see in the example above that the outputs for the first example (x) are identical, but when you use __repr__ and __str__ with a string rather than a number, there's a noticeable difference. Using __repr__ returns an output that is within single and double quotes, while __str__ returns an output exactly as the string appears when it's declared (within single quotes). The quotation marks (and the difference between __repr__ and __str__) matter because an informal representation can't be called as an argument to eval, otherwise the return value wouldn't be a valid string object. If you're going to need to call your output as an argument to eval, make sure you use __repr__ over __str__.