Automatic Generation#

In order to automatically generate a __repr__ for our class, we use the autorepr() class decorator.

For automatic __repr__ creation, Represent assumes that the arguments for __init__ are available as instance variables. If this is not the case, you should use Declarative Generation.

Simple Example#

from represent import autorepr


@autorepr
class Rectangle:
    def __init__(self, name, color, width, height):
        self.name = name
        self.color = color
        self.width = width
        self.height = height

rect = Rectangle('Timothy', 'red', 15, 4.5)
print(rect)
Rectangle(name='Timothy', color='red', width=15, height=4.5)

Pretty Printer#

autorepr() also provides a _repr_pretty_ method for IPython.lib.pretty and a __rich_repr__ method for rich.pretty.

Therefore, with the simple example above, we can pretty print:

from IPython.lib.pretty import pprint

rect.name = 'Something really long to force pretty printing line break'
pprint(rect)
Rectangle('Something really long to force pretty printing line break',
          color='red',
          width=15,
          height=4.5)
from rich.pretty import pprint

pprint(rect)
Rectangle(
    name='Something really long to force pretty printing line break',
    color='red',
    width=15,
    height=4.5
)

Positional Arguments#

Using the positional argument of autorepr() prints some arguments without their keyword as shown here:

@autorepr(positional=1)
class Rectangle:
    def __init__(self, name, color, width, height):
        self.name = name
        self.color = color
        self.width = width
        self.height = height

rect = Rectangle('Timothy', 'red', 15, 4.5)
print(rect)
Rectangle('Timothy', color='red', width=15, height=4.5)

In this case, we passed the number of positional arguments. Similarly, we could have done any of the following:

@autorepr(positional='name')
@autorepr(positional=2)
@autorepr(positional=['name', 'color'])

Inheritance#

Using autorepr() is like defining the following method on the base class:

def __repr__(self):
    return '{self.__class__.__name__}({self.a}, {self.b})'.format(self=self)

Therefore, subclasses will correctly show their own class name, but showing the same attributes as the base class’s __init__.

@autorepr
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

class Cuboid(Rectangle):
    def __init__(self, width, height, depth):
        super().__init__(width, height)
        self.depth = depth

rectangle = Rectangle(1, 2)
print(rectangle)

cuboid = Cuboid(1, 2, 3)
print(cuboid)

Clearly, Cuboid.__repr__ is incorrect in this case:

Rectangle(width=1, height=2)
Cuboid(width=1, height=2)

This is easily fixed by using autorepr() on subclasses if their arguments are different:

@autorepr
class Cuboid(Rectangle):
    def __init__(self, width, height, depth):
        super().__init__(width, height)
        self.depth = depth

Pickle Support#

The deprecated ReprMixin (the predecessor to autorepr()) class required special care when using pickle since it created __repr__ during __init__.

autorepr() has no such limitations, as it creates __repr__ when the class is created.