0

Print has no problem printing a dict:

d = dict()
d['x'] = 'y'
print(d)

{'x': 'y'}

Then why does this fail?

class Utterance:
    def __init__(self, intent_name, text):
        self.intent_name = intent_name
        self.text = text

    def __str__(self):
        return dict(self.__dict__)

print(utterance)
Traceback (most recent call last):
    print(utterance) TypeError: __str__ returned non-string (type dict)

(I know it is standard for __str__ to return string, but I have a reason related to JSON encoding to return dict)

gammay
  • 5,957
  • 7
  • 32
  • 51
  • Have you read this: https://stackoverflow.com/questions/47452513/how-do-you-implement-str-for-a-function? – mx0 Mar 07 '20 at 13:19
  • 2
    The entire **object model** expects `__str__` to well - return a string... even `dict`s `__str__` uses its data to build a string to return... you could do `return str(dict(self.__dict__))`... (or make a custom method to return a dict, and then have your `__str__` method return the `str` of that) – Jon Clements Mar 07 '20 at 13:20
  • 1
    Why not use JSON representation? `return json.dumps(self.__dict__)` – Ionut Ticus Mar 07 '20 at 13:34
  • `__str__` expects a `str` to be returned. – erip Mar 07 '20 at 13:46
  • @lonut Ticus using __dict__ method still doesnt solve my problem. What I need is this (class of dicts) [{'intent_name': 'i1', 'text': 'u1'}, {'intent_name': 'i1', 'text': 'u2'}] {'intent_name': 'i1', 'text': 'u1'} json.dumps(self.__dict__) returns string which is not right here – gammay Mar 07 '20 at 14:31
  • @gammay what problem do you try to solve? what is your expected result? – kederrac Mar 07 '20 at 16:11
  • If you don't want `str`, create another function `my_repr` which can return whatever you need and call `print(utterance.my_repr())` – Ionut Ticus Mar 07 '20 at 21:33

2 Answers2

1

From documentation:

object.__str__(self)
Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.

tl;dr
Why does print expect str to return str?

Because language spec says so.

mx0
  • 6,445
  • 12
  • 49
  • 54
0

object.__str__ is meant to return a human readable string representation of your object, in your case, this method returns a dict, you may use:

class Utterance:
    def __init__(self, intent_name, text):
        self.intent_name = intent_name
        self.text = text

    def __str__(self):
        return self.__dict__.__str__()

print(Utterance(1, 'my_text'))

output:

{'intent_name': 1, 'text': 'my_text'}
kederrac
  • 16,819
  • 6
  • 32
  • 55