ずっと疑問に思っていたPythonにおけるstr()とrepr()の違いについてまとめた。
共通していること
タイトルに「違い」と書き始めたが、まずはこの2つについて共通していることを簡単に書いておく。 この2つの関数について同じことはオブジェクトの中身を出力する関数であるということだ。更にこの2つはPythonの組み込み関数として用意されていて、すぐに使うことができる。
何が違うか
出力する部分が同じであると書いたが、それ以上細分化する部分と必要性はあるのか疑問に思った。Pythonの公式ドキュメントを眺めてみると、repr()には「公式の (official)」、str()は「非公式の (informal)」という文章が書いてある。
repr() 組み込み関数によって呼び出され、オブジェクトを表す「公式の (official)」文字列を計算します。可能なら、これは (適切な環境が与えられれば) 同じ値のオブジェクトを再生成するのに使える、有効な Python 式のようなものであるべきです。
https://docs.python.org/ja/3/reference/datamodel.html#object.__repr__
オブジェクトの「非公式の (informal)」あるいは表示に適した文字列表現を計算するために、 str(object) と組み込み関数 format(), print() によって呼ばれます。戻り値は string オブジェクトでなければなりません。
https://docs.python.org/ja/3/reference/datamodel.html#object.__str__
この公式と非公式の表現が詳細に書かれていないので、余計混乱する形になった。他の人がどう解釈しているかが気になったので、インターネットで検索したところ「エンドユーザにとって読みやすいか読みやすくないか」と書かれていたのが一番しっくり来た。しかし、Pythonの公式ドキュメントに書かれている事実と、これを読む人は開発者であることを考えると、「エンジニアが開発しているときにデバッグとしてわかりやすいものかわかりにくいものか」と解釈するのが正しいように思う。これは開発者から見るか、利用者から見るかの違いなので大筋では同じことを言っているし、「エンドユーザからみて読みやすいか読みにくいか」を否定するものではない。
どう使われているか
実際にどう使われているかを見ていくと、「エンジニアが開発しているときにデバッグとしてわかりやすいものかわかりにくいものか」がしっくり来ると思う。str()とrepr()の違いについて調べると、よく出てくるサンプルコードをGoogle colab上で実行したものだ。strだと単純に時刻表示だけだが、reprだとどのクラスを使っているかとか詳細な情報が出てくる。これを見ると「エンジニアが開発しているときにデバッグとしてわかりやすいものかわかりにくいものか」がある意味では正しい表現であるんじゃないかと思えてくる。
import datetime now = datetime.datetime.now() str(now) 2020-07-31 12:37:54.850396 repr(now) datetime.datetime(2020, 7, 31, 12, 37, 54, 850396) now datetime.datetime(2020, 7, 31, 12, 37, 54, 850396)
また、nowの変数だけ入力した際にデバッグが表示されるのもインタラクティブに開発が行えるPythonの強みが出ていると思う。逆に言えば、.py
ファイルで実行した際はreprの変数だけでコードを書いたときに実行されないので、そういったときのためにstrが用意されているのかなと考えた。