見出し画像

書籍「独学プログラマー」のここは変かも〜? (加筆しました)

書籍「独学プログラマー Python言語の基本から仕事のやり方まで」を見返して、間違ってはいないけど変かもね?、、、と思った箇所があります。。。

「第14章 もっとオブジェクト指向 特殊メソッド」 の、この例題プログラムです。

class Lion:
   def __init__(self, name):
       self.name = name
       
   def __repr__(self):
       return self.name


lion = Lion("Dilbert")
print(lion)

実行結果

Dilbert


print() 組み込み関数で 'Dilbert' を出力する為に、object.__repr__(self) をオーバーライドしている例題プログラムです。

 object.__repr__(self) は、repr() 組み込み関数から呼ばれる特殊メソッドです。本来は、print() 組み込み関数から呼ばれる特殊メソッドという位置づけではありません。
print() 組み込み関数から呼ばれる特殊メソッドは、あくまで object.__str__(self) です。


object.__repr__(self) は、

repr() 組み込み関数によって呼び出され、オブジェクトを表す「公式の (official)」文字列を計算します。可能なら、これは (適切な環境が与えられれば) 同じ値のオブジェクトを再生成するのに使える、有効な Python 式のようなものであるべきです。できないなら、 <...some useful description...> 形式の文字列が返されるべきです。戻り値は文字列オブジェクトでなければなりません。クラスが __repr__() を定義していて __str__() は定義していなければ、そのクラスのインスタンスの「非公式の (informal)」文字列表現が要求されたときにも __repr__() が使われます。

で、、、

object.__repr__(self) は、デバッグの際によく用いられるので、たくさんの情報を含み、あいまいでないような表記にすることが重要なはずです・・・

例題だとしても、、、これだと読者が推奨されない object.__repr__(self) の使い方を覚えそう・・・

ここでオーバーライドすべきメソッドは __repr__() じゃなくて、__str__() でしょう。

例題プログラム説明文の、、、

Lion のオブジェクト(=インスタンス)を print 関数に渡すと、Pythonは object クラスから継承した __repr__ という特殊メソッドを呼び出します。

は、、、正確には、

Lion のオブジェクト(=インスタンス)を print 関数に渡すと、Pythonは object クラスから継承した __str__ という特殊メソッドを呼び出します。__srt__ メソッドのデフォルト実装は、object クラスから継承した  __repr__ という特殊メソッドを呼び出します。

です。。。

繰り返しになるかもしれませんが・・・

__repr__() は、repr() 組み込み関数から呼ばれる特殊メソッドです。本来は、print() から呼ばれる特殊メソッドという位置づけではありません。

__str__() は、str(object) と組み込み関数 format(), print() から呼ばれる特殊メソッドです。

このように __repr__()  をオーバーライドすると、print() 組み込み関数の返り値だけでなく、、、変更されるべきではない repr() 組み込み関数の返り値まで変更されてしまいます。

組み込み関数 print() から呼ばれる特殊メソッドをオーバーライドするなら、__str__() をオーバーライドするべきでしょう。

と言うわけで、、、object.__str__(self) で書き直した例題プログラムです。。

class Lion:
   def __init__(self, name):
       self.name = name
       
   def __str__(self):
       return self.name


lion = Lion("Dilbert")
print(lion)


実行結果

Dilbert



皆さんはどう思いますか?

最後に、Python 3.9.4 ドキュメントの関連部分を引用しておきます。


object.__repr__(self)
repr() 組み込み関数によって呼び出され、オブジェクトを表す「公式の (official)」文字列を計算します。可能なら、これは (適切な環境が与えられれば) 同じ値のオブジェクトを再生成するのに使える、有効な Python 式のようなものであるべきです。できないなら、 <...some useful description...> 形式の文字列が返されるべきです。戻り値は文字列オブジェクトでなければなりません。クラスが __repr__() を定義していて __str__() は定義していなければ、そのクラスのインスタンスの「非公式の (informal)」文字列表現が要求されたときにも __repr__() が使われます。
この関数はデバッグの際によく用いられるので、たくさんの情報を含み、あいまいでないような表記にすることが重要です。
object.__str__(self)
オブジェクトの「非公式の (informal)」あるいは表示に適した文字列表現を計算するために、 str(object) と組み込み関数 format(), print() によって呼ばれます。戻り値は string オブジェクトでなければなりません。
__str__() が有効な Python 表現を返すことが期待されないという点で、このメソッドは object.__repr__() とは異なります: より便利な、または簡潔な表現を使用することができます。
組み込み型 object によって定義されたデフォルト実装は、 object.__repr__() を呼び出します。

Python 3.9.4 ドキュメント




#独学プログラマーPython言語の基本から仕事のやり方まで
#独学プログラマー
#Python #Python3
#__repr__
#__str__