たまに見かけるけれども良くわかっていなかった __repr__() について、似た __str__() と合わせて調べる機会があったのでそのまとめ。
公式チュートリアル
まずは公式チュートリアルを見る。
Object.__repr__(self)
repr()
組み込み関数によって呼び出され、オブジェクトを表す「公式の (official)」文字列を計算します(原文:compute the “official” string representation of an object.)。可能なら、これは (適切な環境が与えられれば) 同じ値のオブジェクトを再生成するのに使える、有効な Python 式のようなものであるべきです。(原文:this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment).)
できないなら、 <...some useful description...>
形式の文字列が返されるべきです。
戻り値は文字列オブジェクトでなければなりません。(原文:The return value must be a string object.)
クラスが __repr__()
を定義していて __str__()
は定義していなければ、そのクラスのインスタンスの「非公式の (informal)」文字列表現が要求されたときにも __repr__()
が使われます。
この関数はデバッグの際によく用いられるので、たくさんの情報を含み、あいまいでないような表記にすることが重要です。(原文:This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.)
object.__str__(self)
オブジェクトの「非公式の (informal)」あるいは表示に適した文字列表現を計算するために、 str(object)
と組み込み関数 format()
, print()
によって呼ばれます。
戻り値は string オブジェクトでなければなりません。(原文:The return value must be a string object.)
__str__()
が有効な Python 表現を返すことが期待されないという点で、このメソッドは object.__repr__()
とは異なります: より便利な、または簡潔な表現を使用することができます。
組み込み型 object
によって定義されたデフォルト実装は、 object.__repr__()
を呼び出します。
かいつまんで言うと
- 戻り値はどちらもString object、と言う点は同じ。
- __repr__()はPythonが再利用出来る様な(=公式の)文字列を返す。
- __repr__()の返すstring objectは、Pythonが再利用する為に、たくさんの情報を含み、あいまいでないような表記(明快な表記)である(= the representation is information-rich and unambiguous)。
- __repr__()はデバッグによく利用される。
- __str__()は対してPythonでの再利用を考慮されていない(=非公式の)文字列を返す。
- __str__()は表示に適した文字列を返す為、logに使用する際に重宝する。
- __repr__(), __str__()どちらも直接使う事は少なく、repr(), str() functionとして使うのが一般の様だ。
まとめると
プログラムの中で使用して、その戻り値を使って別の動きをさせる場合(=コンピューターが読む場合)には__repr__()を使った方が、返ってくる文字データ(string object)が沢山の情報を含み、明快であり有効なPython表現なので好ましい。
そうではなく、Pythonが再利用しにくいけれども、logの出力など、表示に適した(=人間が読みやすい)文字データ(sring object)が欲しい場合には__str__()が好ましい。
と言う事と理解しました。
確認
#実行 import datetime td = datetime.datetime(2021, 1, 19, 0, 0, 0) print(td.__repr__()) print(td.__str__())
上記のコードを実行すると、下記が出力される
# 出力 datetime.datetime(2021, 1, 19, 0, 0) 2021-01-19 00:00:00
確かに__repr__()で出力した方はそのままdatetimeで使用でき、__str__()で出力した方は読みやすいデータになっています。
コメント