__str__ vs __repr__ In Python

Summary: The key goal of __str__ and __repr__ is to return a string representation of a Python object. The way they represent the string object differentiates them.

  • str() & __str()__ return a printable/readable string representation of an object which is focused on the end-user.
  • repr() & __repr()__ return a string representation of an object that is a valid Python object, something you can pass to eval() or type into the Python shell without getting an error. Its major goal is to be unambiguous.

Problem Statement: What is the difference between __str__ and __repr__ in Python?

Firstly, let us discuss why this is one of the most commonly asked questions on the Internet. Let us have a look at an example to understand the reason behind the confusion.

Example 1:

name = 'FINXTER'
print(str(name))
print(repr(name))

Output:

FINXTER
'FINXTER'

Now you see, why this is so confusing! 🤔 Both of them seem to print the string FINXTER. Thus, both of them are built-in functions, and both return a string representation of an object; The only visible difference in this case is – str() prints the string without the quotes (FINXTER), while repr() prints its with the quotes ('FINXTER').

Note: In case you are wondering why are we using repr() and str() instead of __repr__ and __str__ then please have a look at the note given below:

  • __repr__
    • Called by the repr() built-in function
  • __str__
    • Called by the str() built-in function

But now let us have a look at a different example;

Example 2:

from datetime import datetime

d = datetime.now()
print(str(d))
print(repr(d))

Output:

2020-11-04 16:38:20.048483
datetime.datetime(2020, 11, 4, 16, 38, 20, 48483)

In the second example we can clearly visualize the difference between repr() and str().

Let’s have a quick look at what the official documentation says about object.__repr__(self) and object.__str__(self):

object.__repr__(self): Called by the repr() built-in function to compute the “official” string representation of an object.

object.__str__(self): Called by the str() built-in function and by the print statement to compute the “informal” string representation of an object.

In other words, we can say that:

❖ The goal of __repr__ is to be unambiguous

The __repr__() function returns the object representation of any valid python expression such as tupledictionary, string, etc. This means, whenever the repr() function is invoked on the object, it will return the object itself and hence can be evaluated with the eval() function to recreate the object itself because of its unambiguous nature. Thus, repr(25)!=repr("25").

Let us have a look at a quick example where we can use repr() on an expression and evaluate it with the help of eval() function.

Note: You cannot use the eval() function on str() which is clearly depicted in the example below.

Example:

text1 = 'a string'
text2 = eval(repr(text1))
if text1 == text2:
  print("eval() Works!")
text3 = eval(str(text1))
if text1 == text3:
  print("eval() Works!")

Output:

eval() Works!
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    text3 = eval(str(text1))
  File "<string>", line 1
    a string
      ^
SyntaxError: unexpected EOF while parsing

❖ The goal of __str__ is to be readable

The goal of __str__ is not to unambiguous, rather its purpose is to provide a representation that a user that is more readable to the user. Thus, str(25)==str("25") .

Let us have a look at a very simple example which demonstrates the unambiguous nature of repr() and the readability aspect of str().

if str(25)==str("25"):
  print("Goal of __str__ : Readability")
if repr(25)!=repr("25"):
  print("Goal of __repr__ : Unamgiuity")

Output:

Goal of __str__ : Readability
Goal of __repr__ : Unamgiuity

Simply put, __repr__ is for developers while __str__ is for customers!

Points to Remember

❖ For Containers, __str__ Uses The Contained Objects’ __repr__

To simplify things let us take the help of an example:

rank = {'Rick': 1}
language = ['Python', 'Java']
error = (404, 'status_code')
for item in (rank, language, error):
  print(f"{str(type(item)):}")
  print(f"repr() representation: {repr(item):}")
  print(f"str() representation: {str(item)}")
  print("\n")

Output:

<class 'dict'>
repr() representation: {'Rick': 1}
str() representation: {'Rick': 1}


<class 'list'>
repr() representation: ['Python', 'Java']
str() representation: ['Python', 'Java']


<class 'tuple'>
repr() representation: (404, 'status_code')
str() representation: (404, 'status_code')

In the above example, it is clear that even when we use the str() on a container object, the str() function invokes their __repr()__ method; hence we get the object itself as the output and there is no difference between str() and repr() when used with objects. This justifies that for containers __str__ uses contained objects’ __repr__.

❖ The default implementation of __str__ and __repr__ is useless

The default implementation of __str__ and __repr__ is useless and unless you ensure to specifically define and use them, most classes don’t have helpful results for either. Let’s make things clear with the help of another example:

class Finxter(object):
  pass 
print(str(Finxter()))
print(repr(Finxter()))

Output:

<__main__.Finxter object at 0x7f85641d15e0>
<__main__.Finxter object at 0x7f85641d15e0>

As seen above there is no difference between either method and no information beyond the classes id.

Note: An object will behave as though __str__=__repr__ if __repr__ is defined, and __str__ is not.

Now let us try and override the __str__ and __repr__ methods to visualize their behaviour on Coustom Objects. Please follow the example given below.

Example:

class Finxter(object):
  def __str__(object):
     return str("Freelancing")
  
  def __repr__(object):
     return repr("Freelancing")

print(str(Finxter()))
print(repr(Finxter()))
print(eval(repr(Finxter())))

Output:

Freelancing
'Freelancing'
Freelancing

From the above example, it is clear that  __repr__() cab be easily overridden so that repr() works differently.

Note: If you override __repr__, that will also be used for __str__, but vice versa is not possible. Let us have a look at that in the example given below.

Example A: Overriding __repr__ also overrides __str__

class Finxter(object):
  def __repr__(object):
     return repr("Freelancing")

print(str(Finxter()))
print(repr(Finxter()))

Output:

'Freelancing'
'Freelancing'

Example B: Overriding __str__ doesn’t affect __repr__

class Finxter(object):
  def __str__(object):
     return str("Freelancing")

print(str(Finxter()))
print(repr(Finxter()))

Output:

Freelancing
<__main__.Finxter object at 0x7f3b284ef5e0>

Conclusion

Let us summarize the key difference beween __repr__ and __str__

str()repr()
It is the unofficial string representation and used to make the object readable.It is the official string representation and used to make the object unambiguous.
Generates output that is intended for end-users.Generates output that is useful for developers.

Please subscribe and stay tuned for more interesting articles!

Where to Go From Here?

Enough theory, let’s get some practice!

To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?

Practice projects is how you sharpen your saw in coding!

Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?

Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.

Join my free webinar “How to Build Your High-Income Skill Python” and watch how I grew my coding business online and how you can, too—from the comfort of your own home.

Join the free webinar now!