4

I usually write a __repr__ as a way to show how the instance can be re-created in the first place. For example:

class Component:
    def __init__(self, start, end):
        self.start = start
        self.end = end
    def __repr__(self):
        return f'{self.__class__.__name__}(start={self.start}, end={self.end})'

Is there a 'standard' way to write the __repr__, if not, are there suggested options/best-practices for how this should be written, or it's totally subjective?

David542
  • 104,438
  • 178
  • 489
  • 842
  • https://stackoverflow.com/q/1984162/11301900, https://stackoverflow.com/q/1436703/11301900 – AMC Jan 29 '20 at 02:13

1 Answers1

5

The general rule is, if at all possible, produce output that could be typed to recreate the object; from the docs:

If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned.

The second part of that rule is mostly there just to make sure you don't make something that looks like a canonical recreating repr; in practice I've not seen it followed religiously.

For your specific case, I'd recommend only two tweaks:

  1. If a Component might contain another Component as a start or end value, decorate the __repr__ with reprlib.recursive_repr to avoid the possibility of infinite recursion in the case of a Component containing itself (important for libraries, where this might happen regardless of library author intention)
  2. Explicitly use the repr of your attributes with the !r modifier (you don't want the "human friendly" string, you want a representation), changing the string to:

    return f'{self.__class__.__name__}(start={self.start!r}, end={self.end!r})'
    
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271