Pythonの__str__()と__repr__()メソッドの使用方法について
はじめに
この記事では、Pythonデータモデルに定義されている特殊メソッド__str__()と__repr__()について学びます。__str__()と__repr__()メソッドは、オブジェクトについての有用な情報をログに記録したり、出力したりすることでPythonコードのデバッグに役立ちます。
Pythonの特殊メソッドは、二重アンダースコアで始まり、非公式にダンダーメソッドとして知られています。ダンダーメソッドは、Pythonの組み込み演算子や関数の基礎となるメソッドです。ダンダーメソッドを直接呼び出すことは避け、代わりにクラス内でダンダーメソッドを実装し、それらを呼び出す組み込み関数(例:str()やrepr())を使用するべきです。
__str__()と __repr__()の違いは何ですか?
__str__()メソッドは、オブジェクトの人間が読める、または非公式な文字列表現を返します。このメソッドは、組み込みのprint()、str()、format()関数によって呼び出されます。クラスに__str__()メソッドを定義しない場合、組み込みのオブジェクト実装は代わりに__repr__()メソッドを呼び出します。
__repr__()メソッドは、オブジェクトの情報が豊富で公式な文字列表現を返します。このメソッドは、組み込みのrepr()関数によって呼び出されます。可能であれば、返される文字列は、オブジェクトを再作成するために使用できる有効なPython式である必要があります。すべての場合において、文字列は情報を提供し、曖昧さを排除している必要があります。
一般的に、__str__() メソッドはユーザー向けであり、__repr__() メソッドは開発者向けです。
組み込みクラスを使用した__str__()と__repr__()の例
このセクションの例では、デモンストレーションのために __str__() メソッドと __repr__() メソッドを直接呼び出します。
datetime.datetimeクラスは、__str__()と__repr__()メソッドのデフォルト実装を持つ、Pythonの組み込みクラスです。
次の例コードは、datetime.datetimeオブジェクトの__str__()と__repr__()メソッドのデフォルト実装によって返される文字列を示しています。
import datetime
mydate = datetime.datetime.now()
print("__str__() string: ", mydate.__str__())
print("str() string: ", str(mydate))
print("__repr__() string: ", mydate.__repr__())
print("repr() string: ", repr(mydate))
出力結果は: (Shutsuryoku kekka wa)
__str__() string: 2023-01-27 09:50:37.429078 str() string: 2023-01-27 09:50:37.429078 __repr__() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078) repr() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078)
出力によれば、str()関数は__str__()を呼び出して人間にとって分かりやすい文字列を返し、一方repr()関数は__repr__()を呼び出してより情報豊かな文字列を返します。実際、eval()関数と組み合わせてrepr()関数を使用すれば、文字列から新しいオブジェクトを作成することができます。
import datetime
mydate1 = datetime.datetime.now()
mydate2 = eval(repr(mydate1))
print("mydate1 repr() string: ", repr(mydate1))
print("mydate2 repr() string: ", repr(mydate2))
print("the values of the objects are equal: ", mydate1==mydate2)
出力は次の通りです。
mydate1 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) mydate2 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) the values of the objects are equal: True
前の例では、mydate1のrepr()文字列からmydate2オブジェクトを作成し、その後、両オブジェクトの値が等しいことを検証します。
新しいクラスを使用した__str__()と__repr__()の例
クラスを作成する際には、少なくとも__repr__()メソッドを実装する必要があります。これによって、組み込み関数が__repr__()を使用した際に有用な情報が返されます。
以下のクラスは、__str__()や__repr__()メソッドを実装していません。
class Ocean:
def __init__(self, sea_creature_name, sea_creature_age):
self.name = sea_creature_name
self.age = sea_creature_age
c = Ocean('Jellyfish', 5)
print(str(c))
print(repr(c))
str()とrepr()を使用した場合の出力は次のようになります:
<__main__.Ocean object at 0x102892860> <__main__.Ocean object at 0x102892860>
前の例は、オブジェクトの__repr()__のデフォルトの実装が、クラスとオブジェクトIDのみを含んだ16進数形式の文字列を返すことを示していますが、これはあまり役に立ちません。なお、__str__()が実装されていない場合、str()は__repr__()を呼び出しますので、str()とrepr()は同じ値を返します。
オーシャンのクラスを、__str__() メソッドと __repr__() メソッドの実装を追加してアップデートしてください。
class Ocean:
def __init__(self, sea_creature_name, sea_creature_age):
self.name = sea_creature_name
self.age = sea_creature_age
def __str__(self):
return f'The creature type is {self.name} and the age is {self.age}'
def __repr__(self):
return f'Ocean(\'{self.name}\', {self.age})'
c = Ocean('Jellyfish', 5)
print(str(c))
print(repr(c))
出力は:
The creature type is Jellyfish and the age is 5 Ocean(‘Jellyfish’, 5)
前の例での__str__()の実装は、ユーザーに対してオブジェクトの関連する詳細を提供する読みやすい文字列を返します。一方、__repr__()の実装は、オブジェクトを再作成するために使用できる有効なPython式である文字列を返します: Ocean(‘Jellyfish’, 5)。この例では、文字列に対してf-stringフォーマットを使用していますが、Pythonでサポートされている任意のフォーマットを使用して文字列をフォーマットすることもできます。
結論
この記事では、__str__()メソッドと__repr__()メソッドの違いを探り、これらの特殊メソッドをクラスに実装しました。そのため、直接呼び出す必要はありませんでした。Pythonの文字列操作については、弊社のPython文字列チュートリアルでさらに詳しく学びましょう。