Python 错误 TypeError: __str__ Returned Non-String but Printing Output

This article aims to solve the problem that arises when we try to print a string instead of using return statement in a function.


Python returns non-string error but prints output

The following code showsTypeError: str returned non-string, but it still prints the output.

Sample code:

class xy:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        print('X={0}, Y={1}')

if __name__ == "__main__":
    x_y = xy('value of x is 1','value of y is 2')
    print(x_y)

Output:

TypeError                                 Traceback (most recent call last)
<ipython-input-1-7b40a083df6c> in <module>
     10 if __name__ == "__main__":
     11     x_y = xy('value of x is 1','value of y is 2')
---> 12     print(x_y)

TypeError: __str__ returned non-string (type NoneType)

Why do we get the error that __str__ returns a non-string (type NoneType)? First, we need to understand how the __str__ operator works.

__str__The operator is mainly used to return strings, but we mainly use it to print strings. There are two terms for __str__ in Python, which are used interchangeably, operator or Dunder method.

In the above code, the __str__ method directly calls the print() function, which prints the string but does not return the string; this is why it displays the above error.

Furthermore, our __str__ operator prints a string and returns nothing; that's why it incorrectly uses None .


解决 TypeError: __str__ Returned Non-String

We can use the return statement in the __str__ method to solve this problem. So, we have to return the string in the __str__ method instead of printing it. See the code below.

Sample code:

class xy:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return ('X={0}, Y={1}').format(self.x, self.y)

if __name__ == "__main__":
    x_y = xy('value of x is 1','value of y is 2')
    print(x_y)  

Output:

X=value of x is 1, Y=value of y is 2

There is another problem with the above code. The problem is, if the value we return is not a string, it shows the exact error, but this time, the variable type is not None.

Sample code:

class xy:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return 123

if __name__ == "__main__":
    x_y = xy('value of x is 1','value of y is 2')
    print(x_y) 

Output:

TypeError                                 Traceback (most recent call last)
<ipython-input-9-173c41d63dab> in <module>
     12 if __name__ == "__main__":
     13     x_y = xy('value of x is 1','value of y is 2')
---> 14     print(x_y)

TypeError: __str__ returned non-string (type int)

To solve this problem we need to type cast the value and wrap it with str() method which means convert the type of the variable to string as this is str() method requirements.

Sample code:

class xy:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return str(123)

if __name__ == "__main__":
    x_y = xy('value of x is 1','value of y is 2')
    print(x_y)  

Output:

123

Now, the code works for all possible cases because we solved all the expected problems and satisfied the requirement of str method, i.e. it only returns a string value.


__str__ uses __repr__() to return a non-string

__repr__()method does the same thing as the str method. See the code below.

Sample code:

class calculate(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def __repr__(self):
        print ("(%r, %r, %r)" %(self.x, self.y, self.z))

equation = calculate(1, 2, 3)
print(equation) 

Output:

(1, 2, 3)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-0ee74d4c74c8> in <module>
      8 
      9 equation = calculate(1, 2, 3)
---> 10 print(equation)

TypeError: __str__ returned non-string (type NoneType)

The above code also prints the string instead of returning it from the __repr__() method. So, instead of printing the string using __repr__() method, we can use return statement to solve it.

Sample code:

class calculate(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def __repr__(self):
        return str("(%r, %r, %r)" %(self.x, self.y, self.z))

equation = calculate(1, 2, 3)
print(equation)   

Output:

(1, 2, 3)

Guess you like

Origin blog.csdn.net/fengqianlang/article/details/134741395