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__()
にも評価されます。
str()
呼び出し PyObject_Str()
。 Here は、PyObject_Str()
が定義されているソースコードです。このドキュメントで「__str__
」を検索すると、関数が__str__
を呼び出す場所がわかり、戻り値の型が実際に文字列であることを確認できます。
組み込みの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
その制限を適用する関数。
str
はただではありません
def str(obj):
return obj.__str__()
正確な数はわかりませんが、標準の関数や演算子のほとんどが直接そのような魔法のメソッドにマップされていると思います。
str
は__str__
を試行しますが、__repr__
がない場合は__str__
も試行し、str
の戻り値の型を強制します。 (技術的な理由から、戻り値の__init__
も呼び出します str
サブクラスでは奇妙になる可能性があります 。)+
は__add__
を試行しますが、また、__radd__
も試行します。 iter
は__iter__
を試行しますが、__getitem__
も試行します。リストはどんどんと続きます。