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)