Difference between __repr__() vs __str__()

In this tutorial, we will learn the difference between __repr__() and __str__() methods and when these methods should be used. Displaying data to the user is one of the common tasks of the computer program. The program displays the information to the user so that the user can interpret some results. However, a program must also display information to the programmer to develop and maintain it. Programmers require certain information about an object that may not be necessary or understandable for the end user. This is where the distinction between the methods .repr() and .str() becomes important.

A Python object consists of various special methods that provide specific behavior. The __repr__() and __str__() methods are similar special methods that define the object using a string representation. The __repr__() method returns the comprehensive description for a programmer who needs to maintain and debug the code. On the other hand, the __str__() method returns the simpler description to the program user.

We can define these methods in any Python class that allows us to control how the program displays a common object in a different way of output.

Use .__repr__() for Programmers vs .__str__() for Users

Python classes come with several special methods. These methods are presented as double underscores beside their names. These are also known as the dunder methods because of the double underscores in names. The special methods .repr() and .str() provide string representations of an object. A string representation is information about the object. We can also alter the information for different purposes, such as for program users or fellow programmers.

The existence of two different methods to display an object is due to their distinct and separate purposes. Each of the two methods serves a specific role in displaying the object, which is why both are necessary.

  • The method .__repr__() is designed to offer a formal string representation of an object intended for use by the programmer, while the method .__str__() is used to generate an informal string representation of the object that is directed towards the end-user.

The __repr__() method targets the programmer developing and maintaining the program because it provides explicit information about the project. An additional crucial feature of the formal string representation is its ability to allow the programmer to reconstruct an object identical to the original one.

The purpose of the .str() method is to produce a string representation specifically designed for the program's end-user, who may not necessarily possess knowledge of the Python programming language. Consequently, this string representation is crafted to facilitate the user's comprehension of the data contained within the object. Typically, this representation is presented in a more straightforward and user-friendly form.

We can represent both representations of an object using Python's standard REPL.

When an object is evaluated by itself in the REPL, the string representation returned by the .__repr__() method is displayed. On the other hand, if the built-in print() function is used to output the object, then the informal string representation generated by the .__str__() method is displayed instead.

Let's understand the following example.

By invoking the .now() method, we create a datetime.datetime object named "today" that represents the current date and time. When the variable name "today" is evaluated by itself, the REPL displays the formal string representation of the object returned by the .repr() method. This representation includes the data type's name and all the arguments required to re-create the object.

Upon using the print() function, the REPL displays the informal string representation of the object returned by the .str() method. This string representation follows the ISO standard format for displaying dates and times, which is not unique to Python but is widely adopted as a standard for representing dates and times.

Frequently, the formal string representation of an object is a legitimate Python expression that can be utilized to instantiate a new object with the same value. We can verify this by copying the formal string representation of a datetime.datetime object and assigning it to a new variable name. Conversely, trying to process the informal string representation in this manner will not yield the desired outcome.

Example -

When the variable "today" was evaluated in the REPL, the formal string representation produced by the .repr() method was displayed, which can be used to construct a new object identical to the original one.

In contrast, the string representation generated by the .str() method, which was obtained by using the print() function, is not a valid Python expression. Therefore, attempting to utilize it to construct a new object will result in a SyntaxError.

When an object or its variable name is evaluated in the Python REPL, the official string representation specified by the .repr() method is returned. However, when using the print() function, the informal string representation generated by the .str() method is returned instead. The official string representation and the informal string representation are identical or nearly identical. This is primarily because both representations are primarily based on the literals used to instantiate the objects.

In the following example, we represent the lists and dictionaries.

The official and informal string representations of an object are clear and explicit, making them capable of generating a new object with the same value. Additionally, they are straightforward enough for program users to comprehend, as they effectively convey the object's information and cannot be simplified any further. Consequently, objects of this nature do not require distinct string representations for the programmer and the user.

How Can Access an Object's String Representation

So far, we have learned how we can display both string representations in the standard Python REPL. We can also access the official and informal string representation using the built-in function repr() and str(). We can pass an object as an argument in the repr() and str() methods which call the object's __repr__() or __str__(). Let's understand the following example.

Example -

If you pass the variable "today" to Python's built-in repr() function, the program will invoke the object's repr() special method. Although it is possible to call the repr() method directly by using today.repr(), it is generally advisable to use the built-in repr() function instead. This is because accessing special methods directly is discouraged, and these methods are primarily intended to offer additional functionality to an object rather than being called directly.

Define __repr__() and __str__() in a Custom Class

When creating a class, we can define multiple special methods that can enhance the class's functionality. Let's see the following example.

Example -

We define the book class with an __init__() method where we pass the two required argument name and roll_no.

We create an instance of this class with the name and roll number of the student and we pass stu_obj to the print() function. We use print() because when we evaluate a line that only contains the variable name in a script, no output is printed. When you run this script, you get the following output:

We define the book class with an __init__() method where we pass the two required argument names and roll_no.

Output:

<__main__.Student object at 0x2025c8ed0>

This output is the default string representation of an object that's inherited from the object class. The object class is the base class for all Python classes. It shows:

  • __main__.Student: The name of the class and where it's defined
  • 0x2025c8ed0 - The memory address of the object

By default, Python provides a string representation for an object that displays the object's class name and memory address in hexadecimal format. In CPython, the memory address is equivalent to the object's identity. If you need to retrieve the object's identity, you can use the built-in function id(). Unlike the string representation, id() returns an integer value instead of a hexadecimal one.

In most cases, the memory address provided by the default representation of an object could be more useful. This representation doesn't offer valuable information about the object that would benefit the user or the programmer.

Let's understand the following example -

Example -

Output:

<__main__.Student object at 0x000001CDBE6B5310>
<__main__.Student object at 0x000001CDBE6B5310>

We can define the __repr__() special method for the class.

Output:

Student(name='John', roll_no='101')
Student(name='John', roll_no='101')

The .repr() method doesn't accept any additional parameters besides self and must always return a string. As demonstrated in the code snippet, the output confirms that repr(str_obj) and str(str_obj) both produce the string representation that was previously defined.

When we call the built-in function repr() on an object, it invokes the object's .repr() method. On the other hand, if a class doesn't define a .str() method, then the str() method will use the .repr() method as a default.

Now, we will define the __str__() method.

Example -

Output:

Student(name='John', roll_no='101')
John

To define the special method .str(), it should only have the parameter "self" and should return a string. The string representation we choose to return can be the most useful for the program's end user.

By default, the informal string representation returned by the .str() method only displays the student's name and doesn't include the class name reference. However, modifying the informal string representation according to our specific requirements is possible.

Example -

Output:

Student(name='John', roll_no='101')
John's roll_no=101

The official string representation of an object includes all the necessary information that a programmer may require, and it enables them to recreate and explore the object in greater detail. This has two significant advantages:

  • It improves the maintainability of the program.
  • It simplifies the process of debugging.

When creating a class, it is advisable to define the .repr() method to provide the official string representation of the object. By implementing this method, you can avoid the default representation, which is not usually useful. Moreover, this method can be used as a fallback option for the informal string representation when the same representation can be used for both use cases. It can be particularly beneficial in ensuring the object's representation is consistent and efficient.

Conclusion

Throughout this tutorial, we have gained an understanding of the distinction between the official and informal string representations of Python objects. The .repr() method provides the official string representation that is primarily intended for programmers during the development and maintenance of a program. On the other hand, the .str() method returns the informal string representation, which is a more user-friendly format intended for the program's end-users.


Next TopicAnytree Python