Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: When to Use .__repr__() vs .__str__() in Python
One of the most common tasks that a computer program performs is to display data. The program often displays this information to the program’s user. However, a program also needs to show information to the programmer developing and maintaining it. The information a programmer needs about an object differs from how the program should display the same object for the user, and that’s where .__repr__()
vs .__str__()
comes in.
A Python object has several special methods that provide specific behavior. There are two similar special methods that describe the object using a string representation. These methods are .__repr__()
and .__str__()
. The .__repr__()
method returns a detailed description for a programmer who needs to maintain and debug the code. The .__str__()
method returns a simpler description with information for the user of the program.
The .__repr__()
and .__str__()
methods are two of the special methods that you can define for any class. They allow you to control how a program displays an object in several common forms of output, such as what you get from the print()
function, formatted strings, and interactive environments.
In this tutorial, you’ll learn how to differentiate .__repr__()
vs .__str__()
and how to use these special methods in the classes you define. Defining these methods effectively makes the classes that you write more readable and easier to debug and maintain. So, when should you choose Python’s .__repr__()
vs .__str__
?
Free Download: Get a sample chapter from Python Tricks: The Book that shows you Python’s best practices with simple examples you can apply instantly to write more beautiful + Pythonic code.
In Short: Use .__repr__()
for Programmers vs .__str__()
for Users
Python classes have a number of special methods. These methods have a double leading underscore and a double trailing underscore in their names. You can informally refer to them as dunder methods because of the double underscores in their names.
The special methods .__repr__()
and .__str__()
both return string representations of the object. A string representation is a string that shows information about the object. You can tailor this information for different audiences, such as program users or your fellow programmers.
Like with other special methods with leading and trailing double underscores in their names, you can define these methods for any class.
The reason there are two methods to display an object is that they have different purposes:
.__repr__()
provides the official string representation of an object, aimed at the programmer..__str__()
provides the informal string representation of an object, aimed at the user.
The target audience for the string representation returned by .__repr__()
is the programmer developing and maintaining the program. In general, it provides detailed and unambiguous information about the object. Another important property of the official string representation is that a programmer can normally use it to re-create an object equal to the original one.
The .__str__()
method provides a string representation targeted to the program’s user, who may not necessarily be a Python programmer. Therefore, this representation enables any user to understand the data contained in the object. Usually, it’s simpler and easier to read for a user.
Note: For a discussion of these two special methods, check out the The Real Python Podcast: Episode 153.
One way of displaying both representations of an object is by using Python’s standard REPL. The REPL will display the string representation from .__repr__()
when you evaluate a line that only has an object on it. However, the built-in function print()
shows the informal string representation returned by .__str__()
.
You can view the strings returned by .__repr__()
vs .__str__()
for an instance of the datetime
class in the datetime
module:
>>> import datetime
>>> today = datetime.datetime.now()
>>> today
datetime.datetime(2023, 2, 18, 18, 40, 2, 160890)
>>> print(today)
2023-02-18 18:40:02.160890
You create a datetime.datetime
object named today
using .now()
. This method returns the current date and time. When you evaluate the line containing only the variable name today
, the REPL displays the string representation returned by .__repr__()
. This representation shows the name of the data type and all the arguments needed to re-create the object.
When you use print()
, the REPL displays the representation returned by .__str__()
. This string shows the ISO standard format for displaying dates and times. Therefore, this is not a Python-specific format but a standard that’s used more broadly to represent dates and times.
Often, the official string representation is a valid Python expression that you can use to create a new object with the same value. You can confirm this with the datetime.datetime
object by copying the official string representation and assigning it to a new name. You can also attempt to use the informal string representation, but this won’t work:
>>> new_date = datetime.datetime(2023, 2, 18, 18, 40, 2, 160890)
>>> new_date == today
True
>>> new_date = 2023-02-18 18:40:02.160890
Traceback (most recent call last):
...
File "<input>", line 1
new_date = 2023-02-18 18:40:02.160890
^
SyntaxError: leading zeros in decimal integer literals are not permitted ...
The output you got from .__repr__()
when you evaluated today
in the REPL created a new object equal to the original one.
However, the string representation from .__str__()
, which you got when you used print()
, isn’t a valid Python expression, so it raises a SyntaxError
.
You can also show the string representations for common built-in data types:
>>> 5
5
>>> print(5)
5
>>> greeting = "How are you?"
>>> greeting
'How are you?'
>>> print(greeting)
How are you?
Python’s REPL returns the official string representation defined by .__repr__()
when you evaluate a line that includes only the object or its variable name. But what’s happening with print()
? In the examples above, the official string representation is identical or nearly the same as the informal string representation, which print()
returns. Both representations are based largely on the literals that you used to create the objects.
Other built-in data types also have the same official and informal string representations. In these cases, both representations are equal to the literal used for these objects.
Note: Although the two string representations are identical to the literals for most built-in data types, there are some exceptions. For example, set()
is both the informal and official string representation for an empty set since the literal {}
represents an empty dictionary.
You can view the representations for lists and dictionaries in the following example:
>>> [10, 20, 30]
[10, 20, 30]
>>> print([10, 20, 30])
[10, 20, 30]
>>> {"name": "Homer", "role": "author"}
{'name': 'Homer', 'role': 'author'}
>>> print({"name": "Homer", "role": "author"})
{'name': 'Homer', 'role': 'author'}
These representations are unambiguous and can re-create an object with the same value. However, they’re also sufficiently clear for a program’s user because they convey the information contained in the object and can’t be simplified further. These objects don’t need different string representations for the programmer and user.
Note: You can use pretty printing in Python to format your objects in an even more readable format, which can be useful for debugging.
In this section, you’ve learned that the official string representation returned by .__repr__()
contains unambiguous information about the object, aimed at the programmer. You can generally use this representation to create an object with the same values as the original one.
In contrast, the informal string representation returned by .__str__()
is aimed at the user and is normally simpler. The literals used for most built-in data types are used as both the informal and official string representations for these types.
In the next section of this tutorial, you’ll learn about other ways to get the two string representations in Python.
How Can You Access an Object’s String Representations?
You’ve seen how you can display both string representations in the standard Python REPL. Up to this point, you’ve been using special methods to do this. But in general, you can also access the official and informal string representations using the built-in functions repr()
and str()
.
When you pass an object as an argument to either repr()
or str()
, you’re calling the object’s .__repr__()
or .__str__()
method under the hood. You can confirm this using the datetime.datetime
object you created in the previous section:
>>> import datetime
>>> today = datetime.datetime.now()
>>> repr(today)
'datetime.datetime(2023, 2, 18, 18, 40, 2, 160890)'
>>> today.__repr__()
'datetime.datetime(2023, 2, 18, 18, 40, 2, 160890)'
>>> str(today)
'2023-02-18 18:40:02.160890'
>>> today.__str__()
'2023-02-18 18:40:02.160890'
When you pass today
to the built-in function repr()
, the program calls today.__repr__()
. Although you can call the special method directly by calling today.__repr__()
, it’s best to use the built-in function repr()
since you shouldn’t access special methods directly whenever possible. The purpose of special methods is to provide additional functionality to an object rather than to be called directly.
You can use str()
in a similar manner. It calls its argument’s .__str__()
method.
Note: It’s true that on the surface, using str()
looks similar to using repr()
. However, whereas repr()
is a built-in function, str
is a class. Therefore, str()
creates an instance of the str
class by converting its argument to a string. This difference won’t affect how you use str()
and repr()
since the way you use them relies on the fact that they’re both callable and not whether they’re a function or a class constructor.
You must pass the object as an argument to repr()
and str()
. However, .__repr__()
and .__str__()
are methods and don’t require any additional argument. As with all instance methods, the object itself is passed to the method as its first argument. In the case of .__repr__()
and .__str__()
, the object is also the only argument, as these methods don’t take any further arguments.
You can also display the string representations of an object using the built-in function format()
, the string method .format()
, or f-strings. You can start by passing the datetime
object today
to the function format()
and the method .format()
:
>>> format(today)
'2023-02-18 18:40:02.160890'
>>> "{}".format(today)
'2023-02-18 18:40:02.160890'
By default, these return the informal string representation of an object which is returned by .__str__()
. You’ll see how to override the default representation when you explore f-strings in the rest of this section.
You’re most likely to use f-strings when formatting strings since they’re the newest form of string formatting in Python. You can display the object today
using f-strings:
>>> f"{today}"
'2023-02-18 18:40:02.160890'
As was the case with format()
and .format()
, f-strings display the informal string representation that .__str__()
returns. You can get the official string representation from .__repr__()
by using the string conversion flag "!r"
in the f-string:
>>> f"{today!r}"
'datetime.datetime(2023, 2, 18, 18, 40, 2, 160890)'
The conversion flag "!r"
overrides the default for f-strings and calls the object’s .__repr__()
method.
You can also use f-strings with an equal sign (=
) to show both the variable name and its value. You’ll use this option primarily for debugging purposes:
>>> f"{today = }"
'today = datetime.datetime(2023, 2, 18, 18, 40, 2, 160890)'
Note that when you use an equal sign, the f-string defaults to using the official string representation returned by .__repr__()
. The representation aimed at the programmer is the most appropriate in this case since the equal sign in f-strings is normally used for debugging a program.
You can override this behavior using the conversion flag "!s"
:
>>> f"{today = !s}"
'today = 2023-02-18 18:40:02.160890'
When you use the "!s"
conversion, the f-string uses the informal string representation.
In the next section, you’ll learn how to add .__repr__()
and .__str___()
methods to the classes you define.
Should You Define .__repr__()
and .__str__()
in a Custom Class?
When you define a class, you can define several special methods to add functionality to the class. You can read more about defining classes in the tutorial Object-Oriented Programming (OOP) in Python.
You can explore string representation with user-defined classes by defining a class named Book
. You can use a script named book.py
to define this class:
# book.py
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
odyssey = Book("The Odyssey", "Homer")
print(odyssey)
You define the class Book
with an .__init__()
method. There are two required arguments when initializing the class, title
and author
.
You create an instance of this class with the title and author of the book The Odyssey, and you pass odyssey
to the print()
function. You use print()
because when you 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:
$ python book.py
<__main__.Book object at 0x1025c4ed0>
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__.Book
: The name of the class and where it’s defined0x1025c4ed0
: The memory address of the object
This default representation tells you the name of the class and the memory address, which is shown as a hexadecimal value. In CPython, the memory address is the same as the object’s identity. You can find an object’s identity using the built-in function id()
, which returns an integer rather than a hex value.
However, the memory address is rarely useful. This default representation doesn’t provide any additional information about the object that would be useful for the user or the programmer.
Both repr()
and str()
return this string representation by default:
# book.py
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
odyssey = Book("The Odyssey", "Homer")
print(repr(odyssey))
print(str(odyssey))
You call repr(odyssey)
and str(odyssey)
and print out the values they return. The output shows the same default representation for both:
$ python book.py
<__main__.Book object at 0x100d046d0>
<__main__.Book object at 0x100d046d0>
This output confirms that only the default representation is available at the moment.
You can define the .__repr__()
special method for this class:
# book.py
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __repr__(self):
class_name = type(self).__name__
return f"{class_name}(title={self.title!r}, author={self.author!r})"
odyssey = Book("The Odyssey", "Homer")
print(repr(odyssey))
print(str(odyssey))
The .__repr__()
method has no additional parameters other than self
and must always return a string. The output from this code shows that both repr(odyssey)
and str(odyssey)
return the string representation that you just defined:
$ python book.py
Book(title='The Odyssey', author='Homer')
Book(title='The Odyssey', author='Homer')
The repr()
built-in function calls the object’s .__repr__()
method. If a class doesn’t have a .__str__()
method defined, then str()
will also default to the object’s .__repr__()
method.
You define the return value for .__repr__()
to include the name of the class followed by parentheses (()
) and the two arguments required to initialize the class. This format is ideal for the official string representation since it represents a valid Python expression that can re-create an object equal to the original one. Whenever possible, you should use this format for the official string representation.
Next, you can define the .__str__()
method for the class:
# book.py
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __repr__(self):
class_name = type(self).__name__
return f"{class_name}(title={self.title!r}, author={self.author!r})"
def __str__(self):
return self.title
odyssey = Book("The Odyssey", "Homer")
print(repr(odyssey))
print(str(odyssey))
You define the .__str__()
special method, which shouldn’t have any additional parameters other than self
and should return a string. The string representation can be any string that you feel would be most beneficial for the program’s user. The output from this version of the code shows both the official and informal string representations, in that order:
$ python book.py
Book(title='The Odyssey', author='Homer')
The Odyssey
The informal string representation returned by .__str__()
only shows the book’s title and doesn’t have a reference to the class name either. You can customize the informal string representation to suit your needs:
# book.py
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __repr__(self):
class_name = type(self).__name__
return f"{class_name}(title={self.title!r}, author={self.author!r})"
def __str__(self):
return f'"{self.title}" by {self.author}'
odyssey = Book("The Odyssey", "Homer")
print(repr(odyssey))
print(str(odyssey))
The string returned by .__str__()
now has the book’s title in quotation marks followed by the author’s name. Note that if you want to use double quotation marks within a string, you can use single quotation marks to denote the string. The output from this code shows the official representation first, followed by the modified informal string representation:
$ python book.py
Book(title='The Odyssey', author='Homer')
"The Odyssey" by Homer
The official string representation includes all the details needed by a programmer, and it allows you to replicate the object to explore it further. This has a couple of major benefits:
- It makes the program more maintainable.
- It facilitates debugging.
You can use the expression in this string representation to create an object with the same values as the original one. This feature is useful during debugging as you or a fellow programmer replicates an object to explore it further.
However, the informal string representation has a friendlier format that’s better suited for a program’s user. This representation makes the output more readable for a user.
Note: Take extra precautions when implementing these two special methods to ensure that sensitive information, such as user passwords, doesn’t get exposed in any way. It’s best to skip such attributes or at least anonymize them before returning the corresponding string.
When you define a class, it’s a best practice to include the official string representation by defining .__repr__()
. By including this method, you avoid the default representation, which isn’t very useful in most cases. This method will also provide a fallback option for the informal string representation, which comes in handy when you can use the same representation for both use cases.
If you need to display the object to a user, then you can also define .__str__()
. This method will provide an output that’s easier for the user to understand.
If you’re using Python’s data classes, a default official string representation is already included. You don’t need to define .__repr__()
yourself unless you want to override the default format.
You’re now ready to include string representations in any class that you define.
Conclusion
In this tutorial, you’ve learned the difference between official and informal string representations of Python objects. The special method .__repr__()
returns the official string representation, which is aimed at programmers as they develop and maintain a program. The special method .__str__()
returns the informal string representation, a friendlier format for the program’s user.
Now, you can distinguish between these two representations and know which one to expect in different situations. And if you haven’t been doing this already, you’ll never write another class without defining at least the .__repr__()
method to provide the official string representation.
Free Download: Get a sample chapter from Python Tricks: The Book that shows you Python’s best practices with simple examples you can apply instantly to write more beautiful + Pythonic code.
Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: When to Use .__repr__() vs .__str__() in Python