概要
Python
のrepr
関数は、オブジェクトの正式で評価可能な文字列表現を取得するための関数です。この関数は、特にデバッグやログ出力の際に、オブジェクトの内部状態や構造を詳細に把握するために非常に役立ちます。repr
関数は、開発者がオブジェクトの「正確な」姿を確認したい場面で使用され、得られた文字列は再度eval
関数で評価可能な形式であることが多いです。本記事では、repr
関数の基本的な使い方と、str
関数との違い、さらにどのような場面で使えるかについて詳しく解説します。
repr関数の基本構文
repr(object)
パラメータ
object
任意のオブジェクト。repr
関数は、このオブジェクトの正式な文字列表現を返します。
戻り値
repr
関数は、オブジェクトの形式的で評価可能な文字列表現を文字列として返します。
使用例
基本的な使用例
文字列や数値、リストなどの標準的なデータ型に対してrepr
を使うと、その型に応じた正式な表現が返されます。
x = 123
y = "Hello, World!"
print(repr(x)) # 出力: '123'
print(repr(y)) # 出力: "'Hello, World!'"
このように、数値はそのままの形式で、文字列はシングルクオートで囲まれて表示されます。repr
によって返された文字列は、ほぼeval()
で再評価できる形式です。
リストや辞書の表示
複雑なデータ型、例えばリストや辞書に対してもrepr
を使用できます。
lst = [1, 2, 3, "`Python`"]
dct = {"a": 1, "b": 2}
print(repr(lst)) # 出力: "[1, 2, 3, '`Python`']"
print(repr(dct)) # 出力: "{'a': 1, 'b': 2}"
リスト内の文字列もシングルクオートで囲まれ、辞書のキーと値のペアも正確に表現されます。
str関数との違い
Python
にはrepr
関数とよく似たstr
関数がありますが、両者には重要な違いがあります。
repr
関数: オブジェクトの「正式な」文字列表現を返します。この表現は主に開発者向けで、再度評価可能な形式にすることを意図しています。str
関数: オブジェクトの「人間が読みやすい」文字列表現を返します。ユーザー向けに出力する際に使われるのが一般的です。
repr
とstr
の比較例
x = "Hello\nWorld"
print(repr(x)) # 出力: "'Hello\\nWorld'"
print(str(x)) # 出力: "Hello
# World"
この例では、repr
関数が\n
をエスケープして表示しているのに対し、str
関数は改行をそのまま反映しています。repr
は技術的な正確性を重視し、str
は人間が読みやすい出力を意図しています。
カスタムクラスでのrepr
とstr
独自のクラスを作成した場合、repr
とstr
をオーバーライドして、クラスのオブジェクトがどのように表示されるかをカスタマイズすることができます。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person('{self.name}', {self.age})"
def __str__(self):
return f"{self.name}, {self.age}歳"
p = Person("Alice", 30)
print(repr(p)) # 出力: "Person('Alice', 30)"
print(str(p)) # 出力: "Alice, 30歳"
この例では、repr
を使うとオブジェクトの正式な表現(オブジェクトの再構築に使える表現)が表示され、str
を使うとユーザー向けの簡潔な情報が表示されます。
reprを使う主なシーン
デバッグ
repr
関数は、デバッグ時にオブジェクトの内部状態を確認する際に特に有用です。オブジェクトの「生の状態」を正確に出力できるため、開発者が予期しない動作をしているコードの原因を突き止める際に役立ちます。
x = "Hello\nWorld"
print(f"デバッグ情報: {repr(x)}") # 出力: デバッグ情報: 'Hello\nWorld'
このように、エスケープシーケンスや特殊文字が含まれている場合でも、repr
を使えばその正確な内容を確認できます。
ログ出力
repr
は、システムのログを記録する際にも活用できます。repr
を使うことで、ログに出力される内容がオブジェクトの正確な状態を反映するため、後からログを解析する際に役立ちます。
with open('logfile.txt', 'a') as f:
f.write(f"ログ出力: {repr(x)}\n")
テストやアサーション
テストを書く際に、オブジェクトの出力が期待した形式かどうかを確認するためにもrepr
を使うことができます。特に、repr
の出力は詳細であるため、テストがより信頼性の高いものになります。
def test_repr():
p = Person("Alice", 30)
assert repr(p) == "Person('Alice', 30)"
カスタムオブジェクトにおけるreprの重要性
カスタムクラスでrepr
メソッドを定義することは、オブジェクトのデバッグやログ出力を効率的に行うために非常に重要です。特に、オブジェクトの属性や状態を一目で理解できるように設計することで、開発時に大きな助けとなります。
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __repr__(self):
return f"Product(name={self.name!r}, price={self.price})"
p = Product("Laptop", 1000)
print(repr(p)) # 出力: Product(name='Laptop', price=1000)
このように、カスタムクラスでもrepr
を適切に実装することで、オブジェクトの状態を明確に把握できるようになります。
まとめ
Python
のrepr
関数は、オブジェクトの正式な文字列表現を取得するための非常に便利なツールです。特にデバッグやログ出力において、repr
はオブジェクトの内部状態を正確に確認するために不可欠です。また、repr
とstr
の違いを理解することで、開発者はユーザー向けとシステム内部向けの出力を適切に使い分けることができます。repr
を正しく活用し、効率的でトラブルシューティングしやすいコードを書きましょう。