The __repr__() Method in Python

In Python, you can specify a textual representation of an object by implementing the __repr__() method into the class.

For example:

class Fruit:
    def __init__(self, name):
        self.name = name
    
    def __repr__(self):
        return f'Fruit("{self.name}")'

When you print a Fruit object, the __repr__() method gets called automatically and the textual representation is displayed in the console:

banana = Fruit("Banana")
print(banana)

Output:

Fruit("Banana")

In this guide, you learn how and why to use the __repr__() method. You also learn about an alternative method called __str__().

The __repr__() Method in Python

In Python, it is possible to override the default description of a custom object by specifying the __repr__() method into the class.

But why would you want to do this?

Let’s see an example.

Say you have a class Fruit class that looks like this:

class Fruit:
    def __init__(self, name):
        self.name = name

Let’s create a couple of Fruit objects with this class:

banana = Fruit("Banana")
apple = Fruit("Apple")

Now, let’s print these objects into the console:

print(banana)
print(apple)

Output:

<__main__.Fruit object at 0x7f0e2089b4c0>
<__main__.Fruit object at 0x7f0e208008b0>

Now, this output is not particularly useful for any purposes. As it turns out, you can customize this default description. But before going there, let’s inspect where this description originates in the first place.

Whenever you call the print() function on a Python object you are calling a method called __repr__() behind the scenes. In a custom class, it is the default implementation of the __repr__() method that returns a rather unclear description of the string.

<__main__.Fruit object at 0x7f0e2089b4c0>
<__main__.Fruit object at 0x7f0e208008b0>

However, you can get rid of this default description by overriding the __repr__() method in the class.

Changing the default representation can be useful if you want to make some sense of your objects, for example when debugging your code.

According to best practices, if you override the __repr__() method, you should return a string that describes exactly how the object was created.

So for example, if you create objects with the following syntax:

Fruit("Banana")

The overridden __repr__() method should exactly the same as a string:

Fruit("Banana")

But why? Let me explain it a bit later.

First, let’s override the __repr__() method into the Fruit class to change the description of the objects:

class Fruit:
    def __init__(self, name):
        self.name = name
    
    def __repr__(self):
        return f'Fruit("{self.name}")'

Now, let’s create two Fruit objects and print them out:

banana = Fruit("Banana")
apple = Fruit("Apple")

print(banana)
print(apple)

This results in the following output in the console:

Fruit("Banana")
Fruit("Apple")

Awesome. Now you have successfully replaced the default description of an object to something you can make sense of!

At this point, is good to know you can also call the built-in repr() function on an object. This calls the __repr__() method and returns the textual representation:

banana = Fruit("Banana")
apple = Fruit("Apple")

print(repr(banana))
print(repr(apple))

This gives the same result:

Fruit("Banana")
Fruit("Apple")

So, under the hood, calling repr() on an object calls the __repr__() method of the object.

But now, let’s go back to why the __repr__() method should always return a string that describes how the object is created? To understand this, let’s take a look at a built-in function called eval().

The eval() Function in Python

In Python, there is a built-in function called eval() that turns the code from a string into executable Python code.

For example:

eval("print(1 + 2)")

Output:

3

As you can see, the eval() function runs the code inside the string argument. Now, this code could be anything. For example, you can create a new Fruit object using the eval() function:

pineapple = eval('Fruit("Pineapple")')

This is the reason why it is recommended to use __repr__() to return a string that describes how the object was created. This makes it possible to call eval() on the string representation of the object to build another equal object.

For example:

banana = Fruit("Banana")
otherbanana = eval(repr(banana))

print(otherbanana)

Output:

Fruit("Banana")

In this code:

  • The repr(banana) returns a sting Fruit(“Banana”).
  • This is passed into the eval() function.
  • The eval() function then executes the code inside the string. This creates another equal banana object.

Wonderful! Now you understand how to modify the description of a custom object by overriding the __repr__() method.

However, if you look at the string representation output:

Fruit("Banana")

You can see it is somewhat ambiguous for someone who does not know about programming. For example, you do not want to show this kind of string representation for an end-user.

Next, let’s take a look at how you can solve this problem by implementing a user-friendly __str__() method into the class.

The __str__() Method in Python

Obviously, you could modify the __repr__() method to be more clear about the objects. However, you do not want to do this because then calling eval() on the object’s representation would no longer work.

Instead, Python allows you to specify another string representation method called __str__(). This is meant to be as clear of a description of an object as it gets—something you could even show to the end-users.

Now, let’s implement the user-friendly __str__() method into the Fruit class:

class Fruit:
    def __init__(self, name):
        self.name = name
    
    def __str__(self):
        return f"A Fruit object called {self.name}"
    
    def __repr__(self):
        return f'Fruit("{self.name}")'

But how can you show this to the user?

Similar to how you can call __repr__() using the repr() function, you can call __str__() method is using the built-in str() function.

But as it turns out, whenever you call the print() function on an object, in reality:

  • The print() function first checks if the object implements the __str__() method.
  • If it does, that gets printed to the console.
  • If it does not, then __repr__() is called instead.

Now if you create a Fruit object and print it, the __str__() method gets called first, which shows a user-friendly string representation of the object:

banana = Fruit("Banana")
print(banana)

Output:

A Fruit object called Banana

If the __str__() method was not implemented, then the description would be grabbed from the __repr__() function when printing the object.

Conclusion

Today you learned what is the __repr__() method in Python.

To recap, the __repr__() method specifies how an object is described as a string. It is advised to implement this method such that it returns a “developer-friendly” string that describes how the object was created. This is to make it possible to call eval() on the representation to build an identical object.

eval(repr(obj)) = obj

Another method used to represent the object as a string is the __str__() method. This is a more “user-friendly” way to describe an object.

When you call print() function on an object, it first tries to call the __str__() method of the object. If that method is not implemented, it then proceeds to call the __repr__() method.

Thanks for reading.

Happy coding!

Further Reading

50 Python Interview Questions

Leave a Comment

Your email address will not be published.