QuerySet.__str__ = __new_str__が必要な理由


`QuerySet.__str__ = __new_str__` って何故必要なのでしょうか？  
これがないと表示されません。




たぶん, ソースコードには `QuerySet` という名のクラスが存在するのでしょう  
(django よくは知らないけど, [QuerySet
API](https://docs.djangoproject.com/en/4.2/ref/models/querysets/) があるので,
`QuerySet` クラスが用意され利用されてるのかも)

* * *

### 特殊メソッド

(docs.python.org)
[データモデル](https://docs.python.org/ja/3/reference/datamodel.html):
[特殊メソッド名](https://docs.python.org/ja/3/reference/datamodel.html#special-
method-names) より

> クラスは、特殊な名前のメソッドを定義して、特殊な構文 (算術演算や添え字表記、スライス表記など) による特定の演算を実装できます。これは、Python
> の演算子オーバロード ( _operator overloading_ )
> へのアプローチです。これにより、クラスは言語の演算子に対する独自の振る舞いを定義できます。

`object.__repr__(self)`

> [`repr()`](https://docs.python.org/ja/3/library/functions.html#repr)
> 組み込み関数によって呼び出され、オブジェクトを表す「公式の (official)」文字列を計算します。可能なら、これは (適切な環境が与えられれば)
> 同じ値のオブジェクトを再生成するのに使える、有効な Python 式のようなものであるべきです。できないなら、 `<...some useful
> description...>` 形式の文字列が返されるべきです。戻り値は文字列オブジェクトでなければなりません。クラスが
> [`__repr__()`](https://docs.python.org/ja/3/reference/datamodel.html#object.__repr__)
> を定義していて
> [`__str__()`](https://docs.python.org/ja/3/reference/datamodel.html#object.__str__)
> は定義していなければ、そのクラスのインスタンスの「非公式の (informal)」文字列表現が要求されたときにも
> [`__repr__()`](https://docs.python.org/ja/3/reference/datamodel.html#object.__repr__)
> が使われます。
>
> この関数はデバッグの際によく用いられるので、たくさんの情報を含み、あいまいでないような表記にすることが重要です。

`object.__str__(self)`

> オブジェクトの「非公式の (informal)」あるいは表示に適した文字列表現を計算するために、
> [`str(object)`](https://docs.python.org/ja/3/library/stdtypes.html#str)
> と組み込み関数
> [`format()`](https://docs.python.org/ja/3/library/functions.html#format),
> [`print()`](https://docs.python.org/ja/3/library/functions.html#print)
> によって呼ばれます。戻り値は
> [string](https://docs.python.org/ja/3/library/stdtypes.html#textseq)
> オブジェクトでなければなりません。
>
>
> [`__str__()`](https://docs.python.org/ja/3/reference/datamodel.html#object.__str__)
> が有効な Python 表現を返すことが期待されないという点で、このメソッドは
> [`object.__repr__()`](https://docs.python.org/ja/3/reference/datamodel.html#object.__repr__)
> とは異なります: より便利な、または簡潔な表現を使用することができます。
>
> 組み込み型 [object](https://docs.python.org/ja/3/library/functions.html#object)
> によって定義されたデフォルト実装は、
> [`object.__repr__()`](https://docs.python.org/ja/3/reference/datamodel.html#object.__repr__)
> を呼び出します。

例えばこのように使うことができます  
(最後の実行結果に注目)

[code]

    class Point:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def __str__(self):
            return f'({self.x}, {self.y})'
    
        def __repr__(self):
            return f'<{self.__class__.__name__}({self.x}, {self.y})>'
    
    p = Point(10, 20)
    print(p)
    # (10, 20)
    
    display(repr(p))
    # <Point(10, 20)>
    
    def fn(self):
        return f'クラス {self.__class__.__name__}: 値は ({self.x}, {self.y})'
    
    Point.__str__ = fn
    print(p)
    # クラス Point: 値は (10, 20)
    
[/code]

質問のコードでは, `__new_str__` が (どこかで定義した) 関数と思われ

[code]

    QuerySet.__str__ = __new_str__
    
[/code]

これらの何れかでなにか分かるかもしれません(関数だということが分かる程度？)

[code]

    print(__new_str__)
    print(type(__new_str__))
    
    help(__new_str__)
    print(__new_str__.__doc__)
    
[/code]

