HOLIDAY SALE! Save 50% on Membership with code HOLIDAY50. Save 15% on Mentorship with code HOLIDAY15.

2) Classes, Objects, and Methods Lesson

Python __str__() and Python __repr__()

5 min to complete · By Martin Breuss

In this lesson, you'll learn about __str__() and __repr__(), two dunder methods in Python that are used to better document your custom objects.

Readability

The __str__() method helps you to create user-friendly output that describes your object when calling print() or str() on it. You can think of it as being aimed at an end-user.

Str Method Example

Remember seeing output such as <class '__main__.Ingredient'> when you've tried to print your objects? That doesn't seem very descriptive. If you want to show different output when you call print() on an Ingredient() object, you'll have to implement __str__():

class Ingredient:

    """Models a food item used as an ingredient."""
    def __init__(self, name, amount):
        self.name = name
        self.amount = amount

    def expire(self):
        """Expires the ingredient."""
        print(f"whoops, these {self.name} went bad...")
        self.name = "expired " + self.name

    def __str__(self):
        return f"{self.name} ({self.amount})"

In this example code, you've decided that you want to represent an Ingredient() object to your users as name (amount). You did this by implementing __str__() so that it returns a string consisting of the relevant instance variables self.name and self.amount, as well as some minimal formatting.

If you now call print() and pass it to one of your custom objects, you'll see this output:

c = Ingredient("carrot", 5)
print(c)  # OUTPUT: carrot (5)

This new output is more user-friendly and contains all the information that your user will probably want to see when they print() an ingredient.

When you don't implement the __str__() method, Python will fall back to the output of __repr__() when print() is called on a custom object.

Documentation

The __repr__() method is similar to __str__(). The difference between the two is that __repr__() should return an unambiguous description of an object of that class.

class Ingredient:

    """Models a food item used as an ingredient."""
    def __init__(self, name, amount):
        self.name = name
        self.amount = amount

    def expire(self):
        """Expires the ingredient."""
        print(f"whoops, these {self.name} went bad...")
        self.name = "expired " + self.name

    def __str__(self):
        return f"{self.name} ({self.amount})"

    def __repr__(self):
        return f"Ingredient(name={self.name}, amount={self.amount})"

This output should be very clear and concise, but can often turn out to be less user-friendly than __str__(). You can think of it as being aimed at developers and should help them to debug potential issues:

c = Ingredient("carrot", 5)
print(c)  # OUTPUT: carrot (5)
print(repr(c))  # OUTPUT: Ingredient(name=carrot, amount=5)

Every custom class needs to have the __repr__() method implemented. If you don't write it yourself, then the default is used, which gives you the output you've seen before: <class '__main__.Ingredient'>.

Illustration of a lighthouse

Tasks

  • Implement both __repr__() and __str__() in your Ingredient() class.
  • Create some objects and print them out, commenting out the first one, then the other dunder method.

In the next lesson, you'll implement __add__() as an example of how you can prepare your custom objects to work in a way that's familiar to other Python developers.

Colorful illustration of a light bulb

Additional Resources

Summary: Python Dunder Documentation

  • __str__() is used to change the output when calling print() or str()
  • __repr__() is like str but returns an unambiguous representation of the object
  • __repr__() and __str__() are both for understanding and debugging your classes
  • If choosing only one, make sure it's __repr__()