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 toeval()
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:
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 therepr()
built-in function to compute the “official” string representation of an object.
object.__str__(self)
: Called by thestr()
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 tuple, dictionary, 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
, that will also be used for__repr__
, but vice versa is not possible. Let us have a look at that in the example given below.__str__
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!
Coders get paid six figures and more because they can solve problems more effectively using machine intelligence and automation.
To become more successful in coding, solve more real problems for real people. 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?
You build high-value coding skills by working on practical coding projects!
Do you want to stop learning with toy projects and focus on practical code projects that earn you money and solve real problems for people?
🚀 If your answer is YES!, consider becoming 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.
If you just want to learn about the freelancing opportunity, feel free to watch my free webinar “How to Build Your High-Income Skill Python” and learn how I grew my coding business online and how you can, too—from the comfort of your own home.