Python

Python __repr__と__str__

特殊なメソッドを確認する。

__repr__ の説明

Called by the repr() built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an “informal” string representation of instances of that class is required.

This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.

object.__repr__
  • オブジェクトの “公式な” 文字列表現を計算する repr() 組み込み関数によって呼び出される
  • 可能な限り(適切な環境であれば)同じ値のオブジェクトを再生成するのに使用できる有効な Python の式のように見えるべき。できない場合、<…有用な説明…>という形式の文字列が返される
  • 戻り値は、文字列オブジェクトでなければならない
  • あるクラスがrepr()を定義しており、str()を定義していない場合、そのクラスのインスタンスの “非公式な” 文字列表現が必要なときに、repr()が使用される
  • 通常、デバッグのために使用されるため、情報量が多く、具体的なことが重要

つまり、

  • 公式な文字列表現
  • evalで評価できるような形が良い
  • 戻り値は文字列
  • strがなくreprがあるときは、str時はreprを使う

__str__ の説明

Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.

This method differs from object.__repr__() in that there is no expectation that __str__() return a valid Python expression: a more convenient or concise representation can be used.

The default implementation defined by the built-in type object calls object.__repr__().

object.__str__
  • str(object)や組み込み関数 format()、print()によって呼び出され、オブジェクトの “非公式な” またはきれいに印字できる文字列表現を計算する
  • 戻り値は、文字列オブジェクトでなければならない
  • object.repr() とは異なり、 str() が有効な Python の式を返すことは期待されていない。より便利で簡潔な表現を使用できる
  • 組み込み型の object で定義されたデフォルトの実装では object.repr() を呼び出す

つまり、

  • 非公式な文字列表現
  • evalで評価できるような形でなくても良い
  • 戻り値は文字列
  • 組み込み型の object で定義されたデフォルトの実装では object.repr() を呼び出す

サンプルコード

2つを実装した時、片方のみを実装した場合で挙動を確認する。

from __future__ import generators
import inspect


class Test:
    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return f"Test({self.value})"

    def __str__(self):
        return f"値:{self.value}"


class Test_without_repr:
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return f"値:{self.value}"


class Test_without_str:
    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return f"Test_without_str({self.value})"


test = Test(42)
print(test)              # 値:42
print(str(test))         # 値:42
print(repr(test))        # Test(42)
print(eval(repr(test)))  # 値:42

test_without_repr = Test_without_repr(0)
print(test_without_repr)        # 値:0
print(str(test_without_repr))   # 値:0
print(repr(test_without_repr))  # <__main__.Test_without_repr object at 0x0000015B4C61D908>
# print(eval(repr(test_without_repr)))  # ERROR

test_without_str = Test_without_str(-1)
print(test_without_str)              # Test_without_str(-1)
print(str(test_without_str))         # Test_without_str(-1)
print(repr(test_without_str))        # Test_without_str(-1)
print(eval(repr(test_without_str)))  # Test_without_str(-1)