# __str__ & __repr__: Change String Representation In Python

In the program output, we can represent Python strings in two ways. Python supports both informal and formal string representations. When we run the Python program to print the string, we get an informal representation of it in the output.

The `__str__` method in Python is responsible for the informal representation of the object, which we can change to the formal representation by using the `__repr__` method.

In this article, we'll discuss these dunder methods named `__str__` and `__repr__` and how they are used for changing the representation of the string.

## \_\_str\_\_() and \_\_repr\_\_() method

The `__str__()` method returns the object's easily-readable or informal string representation. Python calls the `__str__()` method internally when we call functions like `str()` and `print()`.

The `__repr__()` method, unlike the `__str__()` method, returns a more informative or formal string representation of the object. When the `__str__()` method for the class is not defined, the object calls the `__repr__()` method.

Overall, the `__str__()` method is meant for users, whereas the `__repr__()` method is meant for developers and can be more useful when debugging.

### Default implementation

We can implement these methods within the Python class to see them in action. Let's look at the following example.

```python
# Python class is created
class Product:
    def __init__(self, name, category):
        self.name = name
        self.category = category

# Instantiated the class
data = Product('Ford', 'Car')

# Implemented the __str__() method
print(data.__str__())
print(data.__repr__())
print(data)
```

We created the `Product` class and defined the `__init__` function that takes `name` and `category`. Then we instantiated the class `Product` with the necessary arguments.

Then we implemented the `__str__()` and `__repr__()` methods to the object of the class `Product`.

```bash
<__main__.Product object at 0x000002157F10C370>
<__main__.Product object at 0x000002157F10C370>
<__main__.Product object at 0x000002157F10C370>
```

When we ran the above code, we got the object's location in the processor's memory as a hexadecimal number.

This happened because we didn't implement the `__str__()` and `__repr__()` methods within our class `Product`. Thus, calling the `__str__()` method calls the default `__repr__()` method and shows the same output.

### Custom \_\_str\_\_() method

In the following code, we implemented the custom `__str__()` method that returns a string with some information and then we executed the code to see what would be the output.

```python
# Python class is created
class Product:
    def __init__(self, name, category):
        self.name = name
        self.category = category
    
    # Creating __str__() function
    def __str__(self):
        return f'The {self.name} belongs to category {self.category}.'

# Instantiated the class
data = Product('Ford', 'Car')

# Implemented the __str__() method
print(data.__str__())
print(data.__repr__())
print(data)
```

**Output**

```python
The Ford belongs to category Car.
<__main__.Product object at 0x00000156D7E5C370>
The Ford belongs to category Car.
```

We got the string defined in the class's `__str__()` method when we called the `__str__()` and `print()` methods on the object `data`, but not when we called the `__repr__()` method on the object `data`.

### Only \_\_repr\_\_() method

**What if we only implement the** `__repr__()` **method within the class** `Product`**?**

We've added the `__repr__()` method to the `Product` class, which returns a string containing the product name and category.

```python
# Python class is created
class Product:
    def __init__(self, name, category):
        self.name = name
        self.category = category

    # Creating __repr__() function
    def __repr__(self):
        return f'Product: {self.name} - Category: {self.category}.'

# Instantiated the class
data = Product('Ford', 'Car')

# Called the __str__() method
print(data.__str__())
# Called the __repr__() method
print(data.__repr__())
print(data)
# Called the str() function
print(str(data))
```

**Output**

```bash
Product: Ford - Category: Car.
Product: Ford - Category: Car.
Product: Ford - Category: Car.
Product: Ford - Category: Car.
```

As previously discussed, if `__str__()` is not defined for the class, the object will invoke the class's `__repr__()` method. That's why we got the string even though we called `__str__()`, `print()`, and `str()` on the object `data`.

## Calling \_\_str\_\_() and \_\_repr\_\_() on built-in class

So far, we've used user-defined classes to implement the `__str__()` and `__repr__()` methods. Now we'll look at how these methods are implemented in Python's built-in classes.

We'll see what happens when we call the `__str__()` and `__repr__()` methods on the Python built-in `datetime` module's classes.

```python
import datetime

today = datetime.datetime.today()

print(f'Normal: {today}')
print('-'*20)
print(f'__str__ method: {today.__str__()}')
print(f'str() method: {str(today)}')
print('-'*20)
print(f'__repr__ method: {today.__repr__()}')
print(f'repr() method: {repr(today)}')
```

We used the `__str__()`, `str()`, `__repr__()`, and `repr()` methods on the variable `today` to print the current date and time.

**Output**

```bash
Normal: 2023-04-12 18:16:27.991308
--------------------
__str__ method: 2023-04-12 18:16:27.991308
str() method: 2023-04-12 18:16:27.991308
--------------------
__repr__ method: datetime.datetime(2023, 4, 12, 18, 16, 27, 991308)
repr() method: datetime.datetime(2023, 4, 12, 18, 16, 27, 991308)
```

The output shows that the `__str__()` and `str()` methods returned an informal or easily readable string representation, whereas the `__repr__()` and `repr()` methods returned a more informative or formal string representation.

The `__str__()` method is implemented by default in pre-defined or built-in Python classes, so we don't need to define them explicitly.

## Conclusion

The methods `__str__()` and `__repr__()` are used to represent objects in string format. The `__str__()` method returns a human-readable or informal string representation of the object, whereas the `__repr__()` method returns a more informative or formal string representation of the object.

The `__str__()` method is for users, whereas the `__repr__()` method is for developers because it is more useful when debugging.

For pre-defined or built-in Python classes, we don't need to define the `__str__()` method explicitly because it is implemented by default, whereas for user-defined Python classes, we must define a custom `__str__()` method to get the string representation of the object; otherwise, it will return the object's memory address.

The address of the object is returned by the default implementation of the `__str__()` and `__repr__()` functions on the object of the user-defined Python class. To return the string representation of the object, the custom `__str__()` and `__repr__()` methods must be defined within the class, and if `__str__()` is not defined, the object will call the `__repr__()` method.

---

🏆**Other articles you might be interested in if you liked this one**

✅[How Python sort() and sorted() methods are different and how they are used](https://geekpython.in/python-sort-vs-sorted)?

✅[How to move and locate the file pointer using seek() and tell() in Python](https://geekpython.in/seek-and-tell-in-python)?

✅[All about Python's ABC - What is it and how to use it](https://geekpython.in/abc-in-python)?

✅[Generate and manipulate the temporary files using tempfile in Python](https://geekpython.in/tempfile-in-python).

✅[How to use the super() function in Python classes](https://geekpython.in/super-in-python)?

✅[Get started with FastAPI - A detailed guide](https://geekpython.in/build-api-using-fastapi).

✅[Display images on the frontend using FastAPI](https://geekpython.in/displaying-images-on-the-frontend-using-fastapi).

---

**That's all for now**

**Keep Coding✌✌**
