web-dev-qa-db-ja.com

Python)の__str__メソッドからintを返す

str()メソッドの目的はオブジェクトの文字列表現を返すことであることを知っているので、他の何かを強制的に作成するとどうなるかをテストしたいと思いました。

クラスとオブジェクトを作成しました。

class MyClass(object):

    def __str__(self, a=2, b=3):
        return a + b

mc = MyClass()

私が電話するとき:

print(str(mc))

通訳は不平を言う:

TypeError: __str__ returned non-string (type int)

そして、str()メソッドがintを返そうとしているので、これは完全に理解できます。

しかし、私が試してみると:

print(mc.__str__())

出力を取得します:5。

それで、なぜインタープリターは__str__を直接呼び出すときにintを返すことを許可しますが、str(mc)を使用しているときは許可しません。これは、私が理解しているように、mc.__str__()にも評価されます。

13
Narta

str()呼び出し PyObject_Str()Here は、PyObject_Str()が定義されているソースコードです。このドキュメントで「__str__」を検索すると、関数が__str__を呼び出す場所がわかり、戻り値の型が実際に文字列であることを確認できます。

5
JETM

組み込みのstr関数(およびrepr)は、_.__str___(または_.__repr___)を呼び出すだけでなく、デフォルトで、 ___str___または___repr___メソッドがなく、文字列表現が再帰的であるオブジェクトを処理するための巧妙さはありません。

strおよびreprここ および ここ のソース(C)を確認できます。ご覧のとおり、戻り値の型は___str___および___repr___です。

_if (!PyUnicode_Check(res)) {
    PyErr_Format(PyExc_TypeError,
                 "__str__ returned non-string (type %.200s)",
                 Py_TYPE(res)->tp_name);
    Py_DECREF(res);
    return NULL;
}
_

オブジェクトに対して___str___メソッドを呼び出すだけの場合、Python自体は、___str___と呼ばれるメソッドが文字列のみを返すことを強制しません-それはstrその制限を適用する関数。

4
Josh

strはただではありません

def str(obj):
    return obj.__str__()

正確な数はわかりませんが、標準の関数や演算子のほとんどが直接そのような魔法のメソッドにマップされていると思います。

str__str__を試行しますが、__repr__がない場合は__str__も試行し、strの戻り値の型を強制します。 (技術的な理由から、戻り値の__init__も呼び出します strサブクラスでは奇妙になる可能性があります 。)+__add__を試行しますが、また、__radd__も試行します。 iter__iter__を試行しますが、__getitem__も試行します。リストはどんどんと続きます。

2
user2357112