__str__/__repr__
__str__メソッドはprint文やformat文の引数にオブジェクトが指定された場合に呼び出され、オブジェクトの”非公式の”文字列表現を返す。
__repr__メソッドはより正式なオブジェクトの内容を文字列で返し、2つのオブジェクトの同値性をインタープリタがチェックするときに使われる。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Person:     def __init__(self, name, age):         self.name = name         self.age = age     def __str__(self):         return "<Name:{}, Age:{}>".format(self.name, self.age) john = Person("John", 38) luice = Person("Luice", 32) print(john) print(luice) # <Name:John, Age:38> # <Name:Luice, Age:32> | 
print文やformat文での__str__や__repr__の使われ方は次の通り。
- __str__のみが定義されていれば- __str__が使われる
- __repr__のみが定義されていれば- __repr__が使われる
- __str__と- __repr__の両方が定義されていれば- __str__が使われる
エラー~str()関数による明示的な変換
ただし、以下のように文字列として直接操作しようとするとエラーになる。
| 1 2 3 4 5 6 7 8 9 10 | class Person:     def __init__(self, name):         self.name = name     def __str__(self):         return "My name is {}".format(self.name) john = Person("John") print("Hello, " + john)  # TypeError: Can't convert 'Person' object to str implicitly | 
これはprint文で扱われるかどうか以前の問題で、文字列にオブジェクトを結合しようとしたときに起こる。先行のオペランドが文字列で、その次に結合演算子が出てきたのでオブジェクトを文字列に変換しようとして、”オブジェクトを暗黙で文字列に変換できませんよ”とエラーになる。
また演算の順序を入れ替えると、次のようなエラーになる。
| 1 2 3 4 5 6 7 8 9 10 | class Person:     def __init__(self, name):         self.name = name     def __str__(self):         return "My name is {}".format(self.name) john = Person("John") print(john + " ")  # unsupported operand type(s) for +: 'Person' and 'str' | 
今度はオブジェクトが先行しているので、これに対して+演算子を読んだ瞬間に、インタプリタは”このオブジェクトと文字列の演算子として+はサポートされていない”と言ってくる。
これを解決するには、str()関数でオブジェクトを明示的に文字列に変換してやればよい。
| 1 2 3 4 5 6 7 8 9 10 | class Person:     def __init__(self, name):         self.name = name     def __str__(self):         return "My name is {}".format(self.name) john = Person("John") print("Hello, " + str(john)) # Hello, My name is John |