When you create a class, the default string generated when you print an instance of the class has the form <module.class object at address>:
>>> class Example:
... pass
...
>>> x = Example()
>>> print(x)
<__main__.Example object at 0x0000013D58E1FF10>
There are two methods you can define to make your own display of the class:
__repr__ defines a debug representation of the object.
__str__ defines a print representation of the object.
Example:
>>> class Example:
... def __init__(self, value):
... self.value = value
... def __repr__(self):
... return f'Example(value={self.value})'
... def __str__(self):
... return f'Value = {self.value}'
...
>>> x = Example(7)
>>> x # In the REPL, shows __repr__ string
Example(value=7)
>>> print(repr(x)) # repr() explicitly calls __repr__
Example(value=7)
>>> print(x) # print uses __str__ string
Value = 7
>>> print(str(x)) # str() explicitly calls __str__
Value = 7
When defining classes, consider at least defining __repr__ so it prints useful information about the class as recommended by the __repr__ documentation:
... 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) [e.g. eval(repr(obj))] ...
This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.
Define __str__ if you need a "pretty" print. If __str__ is not defined, str() uses __repr__.
>>> class Game:
... def __init__(self, lives):
... self.lives = lives
... def push(self, num):
... self.lives.append(num)
... def pop(self):
... self.lives.pop()
... def peek(self):
... print(self.lives)
... def __repr__(self):
... return f'Game(lives={self.lives})'
... def __str__(self):
... return f'Lives = {self.lives}'
...
>>> g = Game([1,2,3])
>>> g
Game(lives=[1, 2, 3])
>>> print(g)
Lives = [1, 2, 3]
Note the __repr__ string I used can be evaluated to produce a Game object with the same value as recommended:
>>> g2 = eval(repr(g))
>>> g2
Game(lives=[1, 2, 3])