Python での__str__と__repr__の比較

Aditya Raj 2023年1月30日
  1. Python の str() 関数
  2. Python の __str__() メソッド
  3. Python の repr() 関数
  4. Python の __repr__() メソッド
  5. Python での __str__()__repr__()
  6. まとめ
Python での__str__と__repr__の比較

Python では、通常、str() 関数を使用して任意のオブジェクトを文字列に変換します。同様に、repr() 関数を使用してオブジェクトの文字列表現を取得できます。str()repr() が出力を生成するには、これらの関数に渡されるオブジェクトに、それぞれ __str__() メソッドと __repr__() メソッドが実装されている必要があります。

多くの場合、開発者はこれらのメソッドの機能とユースケースの間で混乱しています。チュートリアルでは、str() 関数と repr() 関数がどのように機能するか、および __str__() メソッドと __repr__() メソッドがオブジェクトの動作にどのように影響するかについて説明します。

Python の str() 関数

str() 関数は、オブジェクトの文字列表現を取得するために使用されます。オブジェクトを入力引数として受け取り、その文字列表現を返します。たとえば、次の例に示すように、浮動小数点数の文字列表現を取得できます。

myNum = 123.456
myStr = str(myNum)
print("The number is:", myNum)
print("The string is:", myStr)

出力:

The number is: 123.456
The string is: 123.456

同様に、以下に示すように、str() 関数を使用して、整数、リスト、セット、タプルなどの組み込みデータ型の他のオブジェクトをそれぞれの文字列表現に変換できます。

myNum = 123
myList = [1, 2, 3, 4, 5]
mySet = {1, 2, 3, 4, 5}
myStr1 = str(myNum)
myStr2 = str(myList)
myStr3 = str(mySet)

print("The number is:", myNum)
print("The string is:", myStr1)
print("The list is:", myList)
print("The string is:", myStr2)
print("The set is:", mySet)
print("The string is:", myStr3)

出力:

The number is: 123
The string is: 123
The list is: [1, 2, 3, 4, 5]
The string is: [1, 2, 3, 4, 5]
The set is: {1, 2, 3, 4, 5}
The string is: {1, 2, 3, 4, 5}

ただし、カスタムクラス定義を使用して定義されたオブジェクトを渡すと、出力は理解できません。これを観察するために、属性 nameage を使用して Student クラスを定義しましょう。

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age


student1 = Student("Aditya", 23)
myStr = str(student1)
print("The string representation of student object is:")
print(myStr)

出力:

The string representation of student object is:
<__main__.Student object at 0x7f6016100070>

ここでは、組み込みのデータ構造を使用して定義されたオブジェクトを変換したときに表示されたほど、関数の出力が理解できないことがわかります。なぜこれが起こるのですか?

オブジェクトを str() 関数に渡すと、クラス定義で定義された __str__() メソッドが呼び出されます。__str__() メソッドは、オブジェクトの文字列表現を返します。str() 関数は同じ文字列を返します。ただし、カスタムクラスを定義する場合、__str__() メソッドはありません。このため、str() 関数の出力はあまり理解できません。

Python の __str__() メソッド

要件に応じて、__str__() メソッドを任意のクラス定義に実装できます。ここでの唯一の制限は、メソッドが文字列値を返さなければならないことです。たとえば、以下に示すように、Student クラスの __str__() メソッドを実装できます。

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        myString = "Name: {} , Age: {}".format(self.name, self.age)
        return myString

__str__() メソッドを実装した後、Student オブジェクトを str() 関数に渡すと、__str__() メソッドによって返されるのと同じ文字列が返されます。次の例は、それがどのように機能するかを示しています。

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        myString = "Name: {} , Age: {}".format(self.name, self.age)
        return myString


student1 = Student("Aditya", 23)
myStr = str(student1)
print("The string representation of student object is:")
print(myStr)

出力:

The string representation of student object is:
Name: Aditya , Age: 23

__str__() メソッドは任意の方法で実装できます。たとえば、以下に示すように、別の方法で Student クラスの __str__() メソッドを定義できます。

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        myString = "Name of student is: {} ,{} is {} years old".format(
            self.name, self.name, self.age
        )
        return myString


student1 = Student("Aditya", 23)
myStr = str(student1)
print("The string representation of student object is:")
print(myStr)

出力:

The string representation of student object is:
Name of student is: Aditya ,Aditya is 23 years old

__str__() メソッドの実装方法は、プログラムの実行に影響しません。__str__() メソッドの出力は、ユーザーに出力を表示するためだけに使用されます。

Python の repr() 関数

repr() 関数は、任意のオブジェクトの正式な文字列表現を取得するために使用されます。また、オブジェクトを入力として受け取り、以下に示すようにオブジェクトの文字列表現を返します。

myNum = 123
myList = [1, 2, 3, 4, 5]
mySet = {1, 2, 3, 4, 5}
myStr1 = repr(myNum)
myStr2 = repr(myList)
myStr3 = repr(mySet)

print("The number is:", myNum)
print("The string is:", myStr1)
print("The list is:", myList)
print("The string is:", myStr2)
print("The set is:", mySet)
print("The string is:", myStr3)

出力:

The number is: 123
The string is: 123
The list is: [1, 2, 3, 4, 5]
The string is: [1, 2, 3, 4, 5]
The set is: {1, 2, 3, 4, 5}
The string is: {1, 2, 3, 4, 5}

repr() 関数の出力は、str() 関数の出力とほぼ同じであることがわかります。ただし、両方の方法の動作は完全に異なります。オブジェクトを str() 関数に渡すと、__str__() メソッドが呼び出されます。一方、オブジェクトを repr() 関数に渡すと、__repr__() メソッドが呼び出されます。次の例は、それがどのように機能するかを示しています。

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        myString = "Name of student is: {} ,{} is {} years old".format(
            self.name, self.name, self.age
        )
        return myString


student1 = Student("Aditya", 23)
myStr1 = str(student1)
myStr2 = repr(student1)
print("The string representation of student object is:")
print(myStr1)
print("The output of repr() is:")
print(myStr2)

出力:

The string representation of student object is:
Name of student is: Aditya ,Aditya is 23 years old
The output of repr() is:
<__main__.Student object at 0x7f6410b78070>

ここでは、__str__() メソッドを使用して Student クラスを定義しました。Student クラスのインスタンスを str() 関数と repr() 関数に渡すと、出力が異なることがわかります。

str() 関数は __str__() メソッドによって返される出力を返し、repr() 関数は __repr__() メソッドによって返される出力を返します。__str__() メソッドを実装しない場合、str() 関数は __repr__() メソッドからの出力も返します。

Python の __repr__() メソッド

__repr__() メソッドは、Python でオブジェクトの正規表現を返します。__repr__() メソッドは、組み込みクラスまたはカスタムクラスのインスタンスであるかどうかに関係なく、Python のすべてのオブジェクトに実装されます。カスタムクラスを使用して定義されたオブジェクトの __repr__() メソッドの定義は、次のように理解できます。

def __repr__(self):
    return "<{0}.{1} object at {2}>".format(
        self.__module__, type(self).__name__, hex(id(self))
    )

ここで、self.__module は現在のオブジェクトが作成されるモジュールを示し、type(self).__name__ はクラスの名前を示し、hex(id(self)) はオブジェクトの ID を示します。16 進形式。次の例は、それがどのように機能するかを示しています。

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        myString = "Name of student is: {} ,{} is {} years old".format(
            self.name, self.name, self.age
        )
        return myString


student1 = Student("Aditya", 23)
myStr = student1.__repr__()
print("The output of __repr__() is:")
print(myStr)

出力:

The output of __repr__() is:
<__main__.Student object at 0x7feb92cc8070>

ここで、__repr__() メソッドの出力がメソッド定義で定義されたスキーマに類似していることがわかります。出力は、オブジェクトが __main__ モジュールで定義されており、Student クラスであることを示しています。出力には、オブジェクトの ID も表示されます。

__repr__() メソッドをオーバーライドすることは常に避けてください。これは、__repr__() メソッドを使用してオブジェクトの正規の文字列表現を作成し、それを使用して同じオブジェクトを再インスタンス化できるためです。

ただし、__repr__() メソッドをオーバーライドすると、eval() 関数を使用して文字列表現からオブジェクトを作成できなくなります。
__str__() メソッドと __repr__() メソッドの基本について説明したので、2つのメソッドの違いをいくつか挙げてみましょう。

Python での __str__()__repr__()

__str__() メソッドは、開発者がカスタマイズできるオブジェクトのユーザー読み取り可能な文字列形式を返します。ただし、__repr__() メソッドは、文字列の正規の文字列表現を返します。場合によっては、__str__() メソッドによって返される文字列は、__repr__() メソッドによって返される文字列と同じである可能性があります。数字の場合、これを観察することができます。

ただし、カスタムクラス定義を使用して文字列またはオブジェクトを取得する場合、__repr__() メソッドによって返される文字列は、__str__() メソッドによって返される文字列とは異なります。次の例は、それがどのように機能するかを示しています。

myStr = "Aditya"
myStr1 = myStr.__repr__()
myStr2 = myStr.__str__()
print("The string is:", myStr)
print("The output from the __repr__() method is:", myStr1)
print("The output from the __str__() method is:", myStr2)

出力:

The string is: Aditya
The output from the __repr__() method is: 'Aditya'
The output from the __str__() method is: Aditya

ここで、__str__() メソッドによって返される文字列が Aditya であることがわかります。一方、__repr__() メソッドは、正規の文字列表現 Aditya を返します。

  • __repr__() メソッドによって返された文字列を eval() 関数に渡すと、オブジェクトが返されます。一方、__str__() メソッドによって返された文字列を eval() 関数に渡すと、Python オブジェクトが返される場合と返されない場合があります。たとえば、次の例を見てください。
myNum = 1234
myNum1 = myNum.__repr__()
myNum2 = myNum.__str__()
print("The number is:", myNum)
print("The output from the __repr__() method is:", myNum1)
print("The output from the __str__() method is:", myNum2)
output1 = eval(myNum1)
print(output1)
output2 = eval(myNum2)
print(output2)

出力:

The number is: 1234
The output from the __repr__() method is: 1234
The output from the __str__() method is: 1234
1234
1234

ここでは、__str__() メソッドと __repr__() メソッドを使用して取得した整数の文字列表現から整数オブジェクトを取得できることがわかります。次に、次の例を見てください。

myStr = "Aditya"
myStr1 = myStr.__repr__()
myStr2 = myStr.__str__()
print("The string is:", myStr)
print("The output from the __repr__() method is:", myStr1)
print("The output from the __str__() method is:", myStr2)
output1 = eval(myStr1)
print(output1)
output2 = eval(myStr2)
print(output2)

出力:

The string is: Aditya
The output from the __repr__() method is: 'Aditya'
The output from the __str__() method is: Aditya
Aditya
/usr/lib/python3/dist-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (3.0.4) doesn't match a supported version!
  warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
Traceback (most recent call last):
  File "/home/aditya1117/PycharmProjects/pythonProject/webscraping.py", line 9, in <module>
    output2 = eval(myStr2)
  File "<string>", line 1, in <module>
NameError: name 'Aditya' is not defined

__repr__() メソッドによって返された文字列から文字列オブジェクトを作成できることがわかります。ただし、__str__() メソッドによって返された文字列を使用して文字列オブジェクトを作成しようとすると、プログラムは NameError 例外に遭遇します。

  • __str__() メソッドをオーバーライドして、必要に応じて実装できます。ただし、__repr__() メソッドをオーバーライドしないでください。
  • __repr__() メソッドは、主に開発者がデバッグ中に使用します。一方、__str__() メソッドは、ユーザーが理解できるオブジェクトのテキスト表現を取得するために使用されます。
  • インタラクティブな Python コンソールで変数の名前またはオブジェクトを入力すると、__repr__() メソッドが呼び出されて出力が生成されます。一方、__str__() メソッドは、変数を print() 関数または str() 関数に渡すときに呼び出されます。
  • クラス定義に __str__() メソッドが含まれていない場合、オブジェクトを str() 関数に渡すときに、__repr__() メソッドが Python インタープリターによって呼び出されます。
  • コンテナオブジェクトを print() 関数に渡すと、要素のクラス定義に __str__() メソッドを実装したかどうかに関係なく、コンテナオブジェクトの要素の __repr__() メソッドが出力されます。

まとめ

この記事では、str() 関数、__str__() メソッド、repr() 関数、および __repr__() メソッドの動作について説明しました。また、__str__() メソッドと __repr__() メソッドの使用法の違いについても説明しました。

両方のメソッドの出力は似ていますが、__repr__() メソッドと __str__() メソッドを互いに大きく異なるものにする明確な違いがあります。文字列表現を使用してオブジェクトを再インスタンス化する必要がある場合は、__repr__() メソッドを使用してオブジェクトの文字列表現を取得することをお勧めします。

一方、__str__() メソッドを使用して、ユーザーに通知する以外にプログラムで使用されない、人間が読める形式のオブジェクトを生成する必要があります。

著者: Aditya Raj
Aditya Raj avatar Aditya Raj avatar

Aditya Raj is a highly skilled technical professional with a background in IT and business, holding an Integrated B.Tech (IT) and MBA (IT) from the Indian Institute of Information Technology Allahabad. With a solid foundation in data analytics, programming languages (C, Java, Python), and software environments, Aditya has excelled in various roles. He has significant experience as a Technical Content Writer for Python on multiple platforms and has interned in data analytics at Apollo Clinics. His projects demonstrate a keen interest in cutting-edge technology and problem-solving, showcasing his proficiency in areas like data mining and software development. Aditya's achievements include securing a top position in a project demonstration competition and gaining certifications in Python, SQL, and digital marketing fundamentals.

GitHub

関連記事 - Python String