Python Do I need to define __repr__() ?

  • Thread starter m4r35n357
  • Start date
654
147
[TLDR] what terrible things will happen if I don't?

I've been searching this for a while and all I have found are various "explanations" that __repr__() should provide an "official" representation of the object (or is it class, or instance?). Also it should be usable as input to eval() - (to construct an instance I suppose . . . ?). The documentation I have seen on the matter assumes that the user already knows what it is for ;)

Anyhow, I have not yet encountered a situation that causes me to believe that I need to define it. Perhaps the use case just doesn't apply to what I am doing (number crunching).
Python:
class Series:

    def __init__(self, jet, diff=False):
        self.jet = jet
        self.n = len(self.jet)
        if diff:
            self.jet[1] = D1
        self.diff_status = diff
Here, jet is a list of floats, diff is a bool, and n in an int. So, is __repr__() supposed to make a string "constructor call" for eval? If so, how should I proceed?
 
10,602
4,147
No you don’t need to define it. It’s for special cases to generate eval() runnable code ie a program writing a program to run except you’re writing an expression / command for eval to run.

https://www.geeksforgeeks.org/str-vs-repr-in-python/

A fun example is to write a recursive expression that runs itself rather like a mirrror reflecting off itself to infinity.
 
654
147
Cheers, I'm glad you said that ;)
 

wle

289
112
It's meant for defining a default print representation for your object -- if you want one. This is what you see if you evaluate an object at the REPL. Most of the built-in types in Python have a print representation that is simply what you would type to create the object, e.g.:
Python:
>>> 3
3
>>> 'hello'
'hello'
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
An exception is functions. They don't have a defined print representation so instead you see generic output telling you the object type and a memory address:
Python:
>>> f = lambda x: x**2
>>> f
<function <lambda> at 0x7f387d33c730>
For object types you define yourself, you'll see output like that unless you create a __repr__ method to print something different. Normally, if you do that, you're supposed to print actual code that could be copied and pasted into the REPL to create the object, if it's sensible to do so. (Notice how the print representation for the string above includes the quotes, for example.) The Fraction class in the standard library shows an example of this:
Python:
>>> from fractions import Fraction
>>> Fraction(1, 2) + Fraction(3, 4)
Fraction(5, 4)
That print output is decided by a __repr__ method defined (in Python 2) like this:
Python:
    def __repr__(self):
         """repr(self)"""
         return ('Fraction(%s, %s)' % (self._numerator, self._denominator))
 
654
147
Python:
    def __repr__(self):
         """repr(self)"""
         return ('Fraction(%s, %s)' % (self._numerator, self._denominator))
Ah, so it is a "constructor call" then. I use __str__() to dump the information that I want (i.e. not all of it!), and that is sufficient. The docs seemed to imply that I should be using __repr__(), but I didn't get why. Thanks for the clarification.
 
25,307
6,424
Ah, so it is a "constructor call" then.
No, it isn't. The constructor for an instance of a class is __init__. __repr__ is just a "special method", which is basically a method that can get called implicitly by the interpreter under certain circumstances (in this case, by calling the repr() built-in function or if a string representation of the object is needed and it has no __str__ method defined).
 
654
147
No, it isn't. The constructor for an instance of a class is __init__. __repr__ is just a "special method", which is basically a method that can get called implicitly by the interpreter under certain circumstances (in this case, by calling the repr() built-in function or if a string representation of the object is needed and it has no __str__ method defined).
What I meant was the output of __repr__ is supposed to be the text of a constructor call, not the __repr__ method itself. This was the information I could not extract from the docs.
 
10,602
4,147
The output of repr() is supposed to be code that eval() can evaluate to print it.

https://www.tutorialspoint.com/What-does-the-repr-function-do-in-Python-Object-Oriented-Programming

While str() mght output "hello" then repr would output print("hello");

It allows a python program to write a python program.

Here's a contrarian view on repr() for a class:

https://www.pythoncentral.io/what-is-the-difference-between-__str__-and-__repr__-in-python/

THe author suggests that every class should have one. In contrast, I have written many python programs in 2.x and 3.x form and never once needed to write a repr function but I can see its utility. However, I don't think every class needs one only those that you might like to use in the manner I described earlier.
 
654
147
While str() mght output "hello" then repr would output print("hello");

It allows a python program to write a python program.
Further clarification, thanks! I am sure now it is not for me, as I do mostly number crunching and don't use the evil() function ;)
 

wle

289
112
Ah, so it is a "constructor call" then.
Not always. __repr__() is the method used by the interpreter to decide how to print objects. The idea is it should use the same syntax that you would in source code. It's useful if you want to use Python interactively or for interactive testing and debugging. You can see the objects and you can copy the output made by __repr__() and paste it back into the interpreter or into a source code file. It's also useful if you want to save objects in a text format (e.g. to save to a text file or send over a network connection) that you can read back into Python later.

Eval is used to define what it should do (it should work such that eval(repr(x)) == x). That does not mean this is how it is actually expected to be used.

An example where __repr__() is really useful but is bending the guideline a little is the output generated for symbolic objects in SymPy. The fact that they have __repr__() methods is what allows you to use Python with SymPy as an interactive calculator, similar to how you normally use tools like Mathematica or Matlab:
Python:
>>> from sympy import symbols, expand
>>> x, y = symbols('x y')
>>> expand((x + y)**3)
x**3 + 3*x**2*y + 3*x*y**2 + y**3
You could copy and paste that last line back in as input to the Python interpreter, but only if you've previously done x, y = symbols('x y').

But no, you don't always need this and your class will work fine without a __repr__() method.


The output of repr() is supposed to be code that eval() can evaluate to print it.

https://www.tutorialspoint.com/What-does-the-repr-function-do-in-Python-Object-Oriented-Programming

While str() mght output "hello" then repr would output print("hello");
repr() returns a string that is supposed to be code to create the object, not to print it. For a string, repr() just returns the same string but with extra quote characters at the beginning and end and extra backslashes if necessary:
Python:
>>> 'hello'
'hello'
>>> repr('hello')
"'hello'"
>>> repr(repr('hello'))
'"\'hello\'"'
>>> repr(repr(repr('hello')))
'\'"\\\'hello\\\'"\''
 
25,307
6,424
The output of repr() is supposed to be code that eval() can evaluate to print it.
No, not to print it. The output of __repr__ is supposed to be code that eval() can evaluate to return a Python object that is the same as the one whose __repr__ was invoked.

While str() mght output "hello" then repr would output print("hello");
No, the __repr__ of a string does not output "print". It just outputs the string with quotes around it.
 
25,307
6,424
Further clarification, thanks!
His clarification is wrong. See posts #10 and #11.

What I meant was the output of __repr__ is supposed to be the text of a constructor call
If you want __repr__ to output a string that eval() can evaluate to construct an object that's the same as the one whose __repr__ was called, yes. For some objects, this is not really needed or feasible; those are the cases where __repr__ just gives you a string like <object object at ...>.

Also note that this only really applies to instances of user-defined classes. Instances of built-in classes such as strings don't need to have their __repr__ output an explicit constructor call, because the interpreter already has syntactic support for them built in. That's why, for example, the __repr__ of a string just outputs the string with quotes around it, not a call to the str() class constructor.
 
25,307
6,424
It's meant for defining a default print representation for your object -- if you want one.
This is a common use (since it's built into the interpreter), but not the only possible one. That's why it's better to describe __repr__ as returning a string that eval() can use to construct the object (as you and I have in more recent posts); this is a general description that applies to any use case, not just printing at the REPL.
 
10,602
4,147
No, the __repr__ of a string does not output "print". It just outputs the string with quotes around it.
My apologies here, I found one example that did that to show what repr(0 could be used for and took it to mean that that was its proper function.

Later examples such as the datetime.now illustrate repr() usage better in the python REPL:

Python:
import datetime

today = datetime.datetime.now()

repr(today)
outputting:

Code:
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'
 

Want to reply to this thread?

"Do I need to define __repr__() ?" You must log in or register to reply here.

Physics Forums Values

We Value Quality
• Topics based on mainstream science
• Proper English grammar and spelling
We Value Civility
• Positive and compassionate attitudes
• Patience while debating
We Value Productivity
• Disciplined to remain on-topic
• Recognition of own weaknesses
• Solo and co-op problem solving
Top