set/list/dictあたりは内部で __str__ではなく __repr__ を呼んでいるっぽい

掲題の件、そういうことです。 __str__() だけ定義しておくと

class Hoge():
    def __init__(self, x):
        self._x = x
    def __str__(self):
        return "Hoge({})".format(self._x)

ちゃんと出てくれない。

> x = {Hoge(1), Hoge(2)}
> print(x)
{<__main__.Hoge object at 0x109fb7880>, <__main__.Hoge object at 0x109fb78e0>}

一方、 __repr__() を定義しておくと

class Hoge():
    def __init__(self, x):
        self._x = x
    def __str__(self):
        return self.__repr__()
    def __repr__(self):
        return "Hoge({})".format(self._x)

ちゃんと出る。

> x = {Hoge(1), Hoge(2)}
> print(x)
{Hoge(1), Hoge(2)}