Python __repr__() か __str__()か。悩んだのでまとめてみた。

Python

たまに見かけるけれども良くわかっていなかった __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__() を呼び出します。

かいつまんで言うと

  1. 戻り値はどちらもString object、と言う点は同じ。
  2. __repr__()はPythonが再利用出来る様な(=公式の)文字列を返す。
  3. __repr__()の返すstring objectは、Pythonが再利用する為に、たくさんの情報を含み、あいまいでないような表記(明快な表記)である(= the representation is information-rich and unambiguous)。
  4. __repr__()はデバッグによく利用される。
  5. __str__()は対してPythonでの再利用を考慮されていない(=非公式の)文字列を返す。
  6. __str__()は表示に適した文字列を返す為、logに使用する際に重宝する。
  7. __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__()で出力した方は読みやすいデータになっています。

コメント

タイトルとURLをコピーしました