__repr__ メソッドの実装
__str__ に加えて、Python は文字列表現のための別の特殊メソッドである __repr__ を提供しています。__str__ が人間が読める表現を提供することを目的としているのに対し、__repr__ は、可能であればオブジェクトを再作成するために使用できる、オブジェクトの明確な表現を提供することを目的としています。
__repr__ メソッドの理解
__repr__ メソッドは、オブジェクトに対して repr() 関数を使用した場合、または対話型セッションでオブジェクトを表示した場合に呼び出されます。eval() に渡すと、同等のオブジェクトを作成する文字列を返す必要があります (可能な場合)。
__repr__ メソッドを含めるように Book クラスを更新しましょう。
-
エディタで book.py を開きます。
-
__repr__ メソッドを含めるようにコードを更新します。
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
def __str__(self):
return f'"{self.title}" by {self.author} ({self.pages} pages)'
def __repr__(self):
return f'Book("{self.title}", "{self.author}", {self.pages})'
## Create book objects
book1 = Book("The Great Gatsby", "F. Scott Fitzgerald", 180)
book2 = Book("To Kill a Mockingbird", "Harper Lee", 281)
## Print the books (uses __str__)
print("String representation (using __str__):")
print(book1)
print(book2)
## Get the representation (uses __repr__)
print("\nRepresentation (using __repr__):")
print(repr(book1))
print(repr(book2))
-
ファイルを保存します。
-
スクリプトを実行します。
python3 book.py
次のような出力が表示されるはずです。
String representation (using __str__):
"The Great Gatsby" by F. Scott Fitzgerald (180 pages)
"To Kill a Mockingbird" by Harper Lee (281 pages)
Representation (using __repr__):
Book("The Great Gatsby", "F. Scott Fitzgerald", 180)
Book("To Kill a Mockingbird", "Harper Lee", 281)
__str__ と __repr__ の違い
__str__ と __repr__ の主な違いは次のとおりです。
__str__ は人間が読める出力を目的としていますが、__repr__ は開発者とデバッグを目的としています。
__str__ が定義されておらず、__repr__ が定義されている場合、Python は str() または print() のフォールバックとして __repr__ を使用します。
__repr__ は、理想的には、eval() に渡されたときにオブジェクトを再作成できる文字列を返す必要がありますが、これは常に可能または必要とは限りません。
__repr__ を使用した eval() 関数
正しく実装されている場合、__repr__ によって返される文字列は、eval() でオブジェクトを再作成するために使用できます。これを実際に見てみましょう。
-
repr_eval.py という新しいファイルを作成します。
-
次のコードを追加します。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Point at ({self.x}, {self.y})"
def __repr__(self):
return f"Point({self.x}, {self.y})"
## Create a point
p1 = Point(3, 4)
## Get the repr string
repr_str = repr(p1)
print(f"Representation: {repr_str}")
## Use eval to recreate the object
p2 = eval(repr_str)
print(f"Recreated object: {p2}")
## Verify they have the same values
print(f"p1.x = {p1.x}, p1.y = {p1.y}")
print(f"p2.x = {p2.x}, p2.y = {p2.y}")
-
ファイルを保存します。
-
スクリプトを実行します。
python3 repr_eval.py
次のような出力が表示されるはずです。
Representation: Point(3, 4)
Recreated object: Point at (3, 4)
p1.x = 3, p1.y = 4
p2.x = 3, p2.y = 4
これは、__repr__ によって返される文字列と eval() 関数を使用して、元のオブジェクトを再作成できることを示しています。
各メソッドを使用するタイミング
- オブジェクトの初期状態を設定するには、
__init__ を使用します。
- エンドユーザー向けに人間が読める表現を提供するには、
__str__ を使用します。
- 開発者とデバッグ向けに、正確で明確な表現を提供するには、
__repr__ を使用します。
実践的な演習:完全な例
3 つの特殊メソッドすべてを使用して Rectangle クラスを作成することにより、すべてをまとめましょう。
-
rectangle.py という新しいファイルを作成します。
-
次のコードを追加します。
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
def __str__(self):
return f"Rectangle with width {self.width} and height {self.height}"
def __repr__(self):
return f"Rectangle({self.width}, {self.height})"
## Create rectangles
rect1 = Rectangle(5, 10)
rect2 = Rectangle(3, 7)
## Display information about the rectangles
print(f"Rectangle 1: {rect1}")
print(f"Area: {rect1.area()}")
print(f"Perimeter: {rect1.perimeter()}")
print(f"Representation: {repr(rect1)}")
print("\nRectangle 2: {0}".format(rect2))
print(f"Area: {rect2.area()}")
print(f"Perimeter: {rect2.perimeter()}")
print(f"Representation: {repr(rect2)}")
## Recreate a rectangle using eval
rect3 = eval(repr(rect1))
print(f"\nRecreated rectangle: {rect3}")
print(f"Is it the same area? {rect3.area() == rect1.area()}")
-
ファイルを保存します。
-
スクリプトを実行します。
python3 rectangle.py
次のような出力が表示されるはずです。
Rectangle 1: Rectangle with width 5 and height 10
Area: 50
Perimeter: 30
Representation: Rectangle(5, 10)
Rectangle 2: Rectangle with width 3 and height 7
Area: 21
Perimeter: 20
Representation: Rectangle(3, 7)
Recreated rectangle: Rectangle with width 5 and height 10
Is it the same area? True
この例は、3 つの特殊メソッド (__init__、__str__、および repr`) が連携して、適切に設計されたクラスを作成する方法を示しています。