私もそうでしたが、他言語からPythonにくると独特のクセに困惑することがあります。

最初に「これは何のためにあるのか」と不思議に思ったのがrepr()です。str()があるのに、どう使い分けたら良いのか理解できませんでした。こういうのは自分なりに概念を理解していないと活用できません。

以下の表に両者の違いをまとめてみました。同じような疑問を持つ他言語経験者の参考になれば嬉しいです。コードの検証にはPython3.6.4を用いました。

関数 戻り値 用途
str(object) objectをユーザーが読みやすい文字列に変換して返す。 エンドユーザーに出力する。
repr(object) objectをeval()再び元のオブジェクトに戻せる文字列に変換して返す。対話モードで出力される文字列。representationの略。 デバッグ用に出力する。

つまり、str()JavaのクラスでオーバーライドするtoString()メソッド(C#ToString()メソッド)のイメージです。

一方repr()引数付きのコンストラクタ(または初期化子)を文字列で返してくれる関数と解釈できます。

datetimeモジュールで確認すると分かりやすいです。

>>> import datetime
>>> today = datetime.date.today()
>>> str(today)
'2018-04-12'
>>> repr(today)
'datetime.date(2018, 4, 12)'
>>> today
datetime.date(2018, 4, 12)
>>> x = eval(repr(today))
>>> today - x
datetime.timedelta(0)

以上のコードでstr(today)で出力される‘2018-04-12’だけではtodayオブジェクトが何者かわかりません。

repr(today)の方はtodayがdatetime.dateオブジェクトであることがわかるのでデバッグの時には役に立ちます。また、対話モードの出力と内容が同じになるのも確認できます。恐らく対話モードの出力であることが、コンパイラ言語の者からだと馴染みにくかったのかもしれません。

eval()を使う機会は実際のところ少ないと思いますが、クラスのなかで自分で__repr__メソッドをコーディングする場合はeval()で元のオブジェクトに戻せるか確認することになります。

eval()とは

ここでeval()とは、引数の文字列をPythonの式として実行する関数です(evaluateの略です)。例えば、eval('3*5')とすると15を出力します。Pythonの式をそのまま実行するので、ユーザーが入力した式を受け入れてしまうとプログラムのセキュリティが低下します。その点は十分な注意が必要です。

ちなみにJavaScriptにも同様の機能をもつeval関数があり、同様にセキュリティの問題が指摘されてます。以下の本では、eval関数の問題点が明確に指摘されています。言語は違いますが、なかなか面白い本ですので、興味があればご一読ください。