項目 22: 辞書やタプルで記録管理するよりもヘルパークラスを使う
長いけど要するに mutable な辞書や要素を位置で指定するタプルを複雑な情報保持に使用するのは止めてクラスを使おうという事だろう。
でも namedtuple
は知らなかった。クラスを作るほどでもないけど辞書や tuple だと心もとない場合に使えそうだ。
項目 23: 単純なインタフェースにはクラスの代わりに関数を使う
他の言語だと、フックが抽象クラスで定義されます。
Java の事を言っているのだろう。まぁ Python を始めとした昨今の LL 言語は大抵関数をファーストクラスオブジェクトとして関数の引数に直接渡すことができるが、
状態を保守するために関数が必要な場合、状態を持つクロージャを定義する代わりに、
__call__
メソッドを提供するクラスを定義することを考える。
なるほど。クロージャを使っていたかもしれない。
項目 24: @classmethod ポリモルフィズムを使ってオブジェクトをジェネリックに構築する
内容が難しくて若干辛みが……。ともかく、Python はクラスに対して __init__
メソッドという 1 つのコンストラクタしかサポートしていないので、代わりのコンストラクタを定義するために @classmethod
を使うこと。
項目 25: 親クラスを super を使って初期化する
親クラスのコンストラクタを単純に (親クラス名).__init__()
で呼び出すと、特にダイヤモンド継承時に親のコンストラクタが不当に 2 回呼びだされてしまい意図しない動作となることが書かれている。こういう場合は組み込み関数 super()
を使うとダイヤモンド継承の頂点の __init__
は 1 回しか呼び出されない。
項目 26: 多重継承は mix-in ユーティリティだけに使う
まぁ多重継承は宜しくないのであまり使わないが mix-in 的要素だったらアリということだろう。
項目 27: プライベート属性よりはパブリック属性が好ましい
Python のプライベート変数 (頭に __
をつける) は厳密には特殊な構文で普通にアクセスできてしまう。
なぜ、プライベート属性の構文は、厳密な可視性を強制しないのでしょうか。最も単純な回答は、よく引用される Python のモットー「みんないい大人なんだから。」です。
Python はそういうところがある言語なのは認識している。定数が無くて UPPER_SNAKE_CASE で書いた変数を定数をみなすところとか。
プライベート属性は、コントロール外のサブクラスによる名前衝突を避けるためだけに使用する。
それが Python 流ということか。プロテクテッドの方がまだマシというのが驚いた。
項目 28: カスタムコンテナ型は collections.abc を継承する
abc は Abstract Base Class (抽象基底クラス) だ。Python でもこれを使えば抽象クラスが使えるということ。