__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 |