Home python How is __repr__ different from __str__?

How is __repr__ different from __str__?

Author

Date

Category

Let’s take a couple of fictional classes as an example:

import requests
class A:
  def __init __ (self, a = "string", b = 10, c = ["a", "b", "c", 1, 2, 3]):
    # parameter c - arbitrary length
    self.a = a
    self.b = b
    self.c = c
class B:
  def __init __ (self, A_object):
    # A_object is an object of type A
    self.neighbor = A_object
    self.session = requests.Session ()

1) How should I write __repr__ and __str__ for these classes?

2) Documentation says that __ repr__ is an unambiguous string representation of an object that can be used to recreate the exact same object, and if that is not possible, then output some useful message . It is very likely that you want to serialize the object this way. What, then, is the difference from the bundle __getstate__ , __setstate__ ? These two methods can also easily return a string, and the requirements for this string are the same – an unambiguous representation of an object. Why duplication?

Conversely, as a replacement for getstate, setstate, you can think of the following:

def __repr __ (self):
  return "A ({a}, {b}, {c})". format (a = self.a, b = self.b, c = self.c)

and then call this:

A1 = A ()
A2 = eval (A1 .__ repr __ ())

3) The same documentation says that __str__ should output a nice, readable informational message that reflects the object. How then can you tell the difference between the result of this method and some useful message from __repr__ ?

4) It is not always possible to represent an object as a string. For example, functions, long collections, other objects without str and without repr. It turns out that in this case either the __repr__ requirement is not met, or it is necessary to display the contents of __dict__ for all such objects, which stores the value of all methods and variables. This solution looks bad, what should I do?

5) Returning to the documentation __repr__ – can you give an example of a situation where it is impossible to unambiguously represent an object as a string? Objects have nothing to do with the quantum world – they are ALWAYS deterministic, there is always a set of variables and a set of methods. but not in vain is this line in the documentation?

6) And then there is __format__ , which should also return a string …


Answer 1, authority 100%

datetime.date illustrates the difference well:

& gt; & gt; & gt; from datetime import date
& gt; & gt; & gt; date.today () # sys.displayhook () uses repr () by default
datetime.date (2016, 6, 13)
& gt; & gt; & gt; print (date.today ()) # print uses str () here
2016-06-13

repr (obj) returns a unambiguous text representation of an object useful for debugging, error messages, REPL, which (sometimes) allows it (theoretically) to be restored: eval (repr (obj)) == obj .

str (obj) returns readable text. For many objects, it makes sense to define __repr __ () (since the default implementation in object .__ repr__ is not very informative). It makes sense to define __str __ () for objects for which there is a “natural” human-readable (non-Python-specific) representation (as in the date example), for example, for logs.

If __str__ is not defined, then str () uses repr () .

Different formats are designed for different users (human / program, Python / general purpose). Here’s a graph to illustrate when different formats are useful:

^ ^
| | More human friendly
| + --- +
| | str |
| + --- +
|
| + ---- + + ---- +
| | repr | | json |
| + ---- + + ---- +
|
| + ------ +
| | pickle |
| + ------ +
|
| | Machine readable
+ --------------------------------- & gt;
Python specific - & gt; More general

1) How should I write __repr__ and __str__ for these classes?

class A:
  def __repr __ (self):
    return "A (% r,% r,% r)"% (self.a, self.b, self.c)
class B:
  def __repr __ (self):
    return "& lt; B (neighbor =% r), session =% r & gt;" % (self.neighbor, self.session)

B objects cannot be restored from repr () .

2) The documentation says that __repr__ is an unambiguous representation of an object in the form of a string, which can be used to recreate the exact same object, and if this is not possible, then output some useful message. It is very likely that you want to serialize the object this way. What, then, is the difference from the bundle __getstate__ , __setstate__ ? These two methods can also easily return a string, and the requirements for this string are the same – an unambiguous representation of an object. Why duplicate?

pickle (__getstate __ / __ setstate__ ) is not a human readable format. Design goals and constraints are different. Just because eval (repr (obj)) sometimes works doesn’t mean it’s a good idea to use it instead of pickle.loads (pickle.dumps (obj)) or json.loads (json.dumps (obj)) .

The main consumer of repr () is a human. The pickle.dumps () consumer is typically a program, for example multiprocessing uses pickle to exchange data between processes.

3) The same documentation says that __str__ should output a nice, readable informational message that reflects the object. How then can you tell the difference between the result of this method and some useful message from __repr__ ?

If you don’t see the type name, then it’s not __repr __ () (with the obvious exception of constants (Python literals) such as 'abc' , 123 ).

4) It is not always possible to represent an object as a string. For example, functions, long collections, other objects without str and without repr. It turns out that in this case either the __repr__ requirement is not met, or it is necessary to display the contents of __dict__ for all such objects, which stores the value of all methods and variables. This solution looks bad, what should I do?

eval (repr (obj)) is a hint, not a requirement: if the object is large, then obviously you need to shorten its representation. In many cases, you can use ellipsis:

& gt; & gt; & gt; numpy.arange (10000000)
array ([0, 1, 2, ..., 9999997, 9999998, 9999999])
& gt; & gt; & gt; print (numpy.arange (10000000))
[0 1 2 ..., 9999997 9999998 9999999]

Again: the consumer repr () is the Python programmer who sees this view in the REPL or debugger.

5) Returning to the documentation __repr__ – can you give an example of a situation where it is impossible to unambiguously represent an object as a string? Objects have nothing to do with the quantum world – they are ALWAYS deterministic, there is always a set of variables and a set of methods. but not in vain is this line in the documentation?

The documentation talks about the case where eval (repr (obj)) == obj doesn’t make sense:

& gt; & gt; & gt; object ()
& lt; object object at 0x7f9ff2c8c1d0 & gt;

6) And then there is __format__ , which should also return a string …

This special method allows a type to override how format () behaves, for example:

& gt; & gt; & gt; "{:% Y-% m-% d}". Format (datetime.today ())
'2016-06-13'

Python 2 has __unicode __ () as __str __ () , but unicode returns. Also __fspath __ () (PEP 519) appeared. There may be other protocols that return strings (with their own rationale).

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions