Python class __repr__ method converts string

Python class’s __repr__ method converts a string. After defining a custom class in Python, if you try to output its instance in the console or view it in the interpreter session, you won’t get very satisfactory results. The default “convert to string” functionality is very primitive and lacks detail:

class Car:
def __init__(self, color, mileage):
self.color = color
self.mileage = mileage

>>> my_car = Car('red', 37281)
>>> print(my_car)
<__console__.Car object at 0x109b73da0>
>>> my_car
<__console__.Car object at 0x109b73da0>

By default, you get a string containing the class name and the object instance id (which is the memory address of the object in CPython). While better than nothing, it’s still pretty useless.

You might be able to work around this by printing the class attributes directly, or by adding a custom to_string() method to the class:

>>> print(my_car.color, my_car.mileage)
red 37281

This general idea is correct, but it ignores Python’s conventions and built-in mechanisms for converting objects to strings.
So instead of building your own string conversion mechanism, add the double-underscore methods __str__ and __repr__ to your class. These two methods convert objects to strings in different situations in a Pythonic way.

Let’s see how these methods work in practice. First, add a __str__ method to the previous Car class:

class Car:
def __init__(self, color, mileage):
self.color = color
self.mileage = mileage

def __str__(self):
return f'a {self.color} car'

When you try to print or view a Car instance, you get a slightly improved result:

>>> my_car = Car('red', 37281)
>>> print(my_car)
'a red car'
>>> my_car
<__console__.Car object at 0x109ca24e0>

Viewing the Car object in the console still returns the same result containing the object’s id, but printing the object now returns the string returned by the newly added __str__ method.

__str__ is a double-underscore method in Python that is called when attempting to convert an object to a string:

>>> print(my_car)
a red car
>>> str(my_car)
'a red car'
>>> '{}'.format(my_car)
'a red car'

With a proper __str__ implementation, you can print objects without worrying about directly printing object attributes or writing a separate to_string() function. This is Python’s signature string conversion method.

By the way, some people call Python’s double-underscore methods “magic methods.” There’s nothing magical about these methods; starting them with double underscores is just a naming convention that indicates they’re a core Python feature. Furthermore, adding double underscores helps avoid duplicating names with your own methods and attributes. Object constructors, such as __init__, follow this convention; there’s nothing magical or mysterious about them.

So don’t be afraid to use Python’s double-underscore methods; they’re incredibly useful.

Python Class’s repr Method for String Conversion: __str__ vs. __repr__

Let’s continue with the string conversion problem. From the previous section, if you inspect my_car in the interpreter session, you’ll still get the strange <Car object in 0x109ca24e0>.

This happens because in Python 3, there are actually two double-underscore methods that can convert objects to strings. The first is __str__, which we just introduced; the second is __repr__, which works similarly to __str__ but is used in a different context.

Here’s a simple experiment to help you understand the use cases of __str__ and __repr__. Let’s redefine the Car class and add two double-underscore methods for converting to strings, producing different output:

class Car:
def __init__(self, color, mileage):
self.color = color
self.mileage = mileage

def __repr__(self):
return '__repr__ for Car'

def __str__(self):
return '__str__ for Car'

When you try the above example, you can see that each method generates the corresponding string conversion result:

>>> my_car = Car('red', 37281)
>>> print(my_car)
__str__ for Car
>>> '{}'.format(my_car)
'__str__ for Car'
>>> my_car
__repr__ for Car

Experimentally, when you inspect an object in a Python interpreter session, you get the object’s __repr__ result.

Interestingly, containers like lists and dictionaries always use the result of __repr__ to represent the contained object, even when calling str() on the container itself:

str([my_car])
'[__repr__ for Car]'

Instead of manually selecting one string conversion method over another, such as to more clearly convey the intent of your code, it’s better to use the built-in str() and repr() functions. Using these two functions is preferable to calling an object’s __str__ or __repr__ directly because the results are the same but more aesthetically pleasing:

>>> str(my_car)
'__str__ for Car'
>>> repr(my_car)
'__repr__ for Car'

After introducing __str__ and __repr__, you might wonder how they differ in practice. Since these two functions seem to serve the same purpose, it might be confusing when to use them.

For this question, consider how the Python standard library handles it. Let’s create another experiment and see how it uses __repr__ and __str__ to control string conversion:

>>> import datetime
>>> today = datetime.date.today()

For date objects, the __str__ function returns a concise text representation that can be displayed to users with confidence. So, when you call str() on a date object, you get something that looks like an ISO date format:

>>> str(today)
'2017-02-02'

__repr__ focuses on obtaining an unambiguous result; the generated string is primarily intended to help developers debug their programs. To be as explicit as possible about what this object is, calling repr() on it produces a more complex result, even including the full module and class name:

>>> repr(today)
'datetime.date(2017, 2, 2)'

Copying and pasting the string returned by this __repr__ statement recreates the original date object as a valid Python statement. This is a nice practice and a good example to learn from when writing your own repr__ statements.
However, I find this pattern quite difficult to implement and is generally not worth the extra work. My rule of thumb is to make the string generated by __repr__ clear and helpful to the developer; it doesn’t need to be possible to recover the object’s full state.

Python Class repr Method Converts Strings to __repr__

If you don’t provide a __str__ method, Python will fall back to the result of __repr__ when looking for __str__. Therefore, it’s recommended to always add a __repr__ method to your custom classes; it takes very little time but ensures usable string conversion results in almost all cases.

The following describes how to quickly and efficiently add basic string conversion functionality to your custom classes. For the previous Car class, first add a __repr__:

def __repr__(self):

return f'Car({self.color!r}, {self.mileage!r})'

Here, the !r conversion flag ensures that the output strings use repr(self.color) and repr(self.mileage) instead of str(self.color) and str(self.mileage).
While this works correctly, it has the disadvantage of hard-coding the class name in the format string. A trick to avoid this hard-coding is to use the object’s __class__.__name__ attribute to get the class name as a string.
The advantage of this approach is that changing the class name doesn’t require modifying the implementation of __repr__, thus better adhering to the “Don’t Repeat Yourself” (DRY) principle:

def __repr__(self):
return (f'{self.__class__.__name__}('
f'{self.color!r}, {self.mileage!r})')

The disadvantage is that the format string is very long and unwieldy. However, if carefully formatted, it can still maintain good code form and comply with PEP 8 standards.
With the above implementation of __repr__, we get useful results when inspecting the object directly or calling repr():

>>> repr(my_car)
'Car(red, 37281)'

Printing the object or calling str() will return the same string because the default implementation of __str__ simply calls __repr__:

>>> print(my_car)
'Car(red, 37281)'
>>> str(my_car)
'Car(red, 37281)'

I think this is a standard approach that gets the job done with less effort and is straightforward to use in most cases. Therefore, I always add a basic __repr__ implementation to my custom classes.
Here is a complete example for Python 3, including an optional __str__ implementation:

class Car:
def __init__(self, color, mileage):
self.color = color
self.mileage = mileage

def __repr__(self):
return (f'{self.__class__.__name__}('
f'{self.color!r}, {self.mileage!r})')

def __str__(self):
return f'a {self.color} car'

Differences between Python class repr method for converting strings and __unicode__

In Python 3, the str data type is used to represent text, which uses Unicode characters to represent most writing systems in the world.

Strings are represented using a different data model. There are two types for representing text: str (limited to the ASCII character set) and unicode (equivalent to Python 3’s str).

Due to this difference, Python 2 has an additional double-underlined method that controls string conversion: __unicode__. In Python 2, __str__ returns bytes, while __unicode__ returns characters.

Using the new __unicode__ method to convert strings is preferred in most cases. There is also a built-in unicode() function that calls the corresponding double-underlined method, similar to how str() and repr() work.

So far so good, but the rules for calling __str__ and __unicode__ in Python 2 are quite quirky: the print statement and str() call __str__; the built-in unicode() first calls __unicode__, and if __unicode__ isn’t available, it falls back to __str__, which decodes the result using the system text encoding.
Compared to Python 3, these special cases make the text conversion rules more complicated. However, they can be simplified for practical situations. Unicode is the preferred and trending approach for text processing in Python programs.
So, in general, it’s recommended to put all string formatting code in the __unicode__ method, then create a __str__ stub implementation that returns the Unicode representation encoded in UTF-8:

def __str__(self):
return unicode(self).encode('utf-8')

The __str__ stub function will be identical in most custom classes, so you can copy and paste it as needed (or place it in a base class). All string conversion code generated for non-developers should be in __unicode__.
Here’s a complete example for Python 2.x:

class Car(object):
    def __init__(self, color, mileage):
        self.color = color
        self.mileage = mileage

    def __repr__(self):
       return '{}({!r},
           {!r})'.format( self.__class__.__name__,
           self.color, self.mileage)

    def __unicode__(self):
        return u'a {self.color}
            car'.format(self=self)

    def __str__(self):
        return unicode(self).encode('utf-8')

Key Points

  • Use the double-underscore methods __str__ and __repr__ to take control of string conversion within your class.

  • __str__ should produce readable results. __repr__ should produce unambiguous results.

  • Always add __repr__ to your class. __str__ calls __repr__ by default.

  • Use __unicode__ instead of __str__ in Python 2.

Leave a Reply

Your email address will not be published. Required fields are marked *