Why can an atribute have a .__str__()?

I was coding a class and a teammate did a peculiar thing:

class Dog:

    def __init__(self, hunger, size, cute):
        self.__hunger = hunger
        self.__size = size
        self.__cute = cute

    def __str__(self):
        data_1 = self.__hunger.__str__() # Why is this allowed?
        data_2 = self.__size.__str__()
        data_3 = self.__cute.__str__()
        return f"The dog is {data_1} and {data_2} but is also {data_3}"

a = Dog(20, 120, True)
print(a)

He assigned an attribute with .__ str __(). Instead of just:

    def __str__(self):
        data_1 = str(self.__hunger)
        data_2 = str(self.__size)
        data_3 = str(self.__cute)
        return f"The dog is {data_1} and {data_2} but is also {data_3}"

Why is .__ str __ allowed? and in what does it differ from the "normal" approach of just using str()?

>Solution :

str(x) very simply calls x.__str__().

So, the usages are the same.

The recommended practice is to use str(x), however. Very rarely is it correct to directly invoke the special dunder ( __xxx__ ) functions.

Leave a Reply