先日からちょこちょこ読んでいるオライリーPython豆知識収集の続きの、続き。とうとうクラス、ひいてはオブジェクト指向の範疇に突入し、なんとか読み終えたぜ。今回の読書を通じてプログラミング初心者絶対殺すワード「オブジェクト指向」が理解できた気がするので、それもあわせて書く。

  • クラスもインスタンスもオブジェクトのひとつ。
  • {インスタンス名}.{属性名} と書いたとき、属性名の検索は、インスタンス→サブクラス→スーパークラスの順に行われる。
  • 多重継承とは、ひとつのクラスがふたつ以上のスーパークラスをもつことである。
  • IS-A関係とは、派生(サブ)クラスから見た基底(スーパー)クラスとの関係である。he is a man, man is a creatureという文で関係を表せることからついた名前。
  • 演算子のオーバーロードとは、インスタンスオブジェクトを演算子に対応できるようにすることである。が、よくわからんし「初心者はあんまし使わなくていいよ」って書かれてるのでそれに甘えることにして飛ばした。
  • クラスは単なる名前空間であり、変数を定義するツールである。
  • メソッドの呼び出しは、 {インスタンス名}.{メソッド名}(引数) って書いてもいいし {クラス名}.{メソッド名}(インスタンス名, 引数) って書いてもいい。ほう、ようやくメソッド定義のときに使うselfの意味がわかったぜ。
  • 前者を結合メソッドといい、後者のことは非結合メソッドという。
  • assert文は式がFalseのとき任意の文字列を表示できる。これはエラーチェックに使えそうでいいですね。
assert {式}, "エラーメッセージ"
  • クラス内の変数は「クラスの属性」といい、 self. のついてるのは「インスタンスの属性」。
  • {インスタンス名}.__class__ でインスタンスがリンクしてるクラスがわかる。
  • {クラス名}.__bases__ でクラスのスーパークラスがわかる。
  • コンポジションとは、クラスメソッドの中で他のクラスのインスタンスを作成することである(よくわからん)。
  • デリゲーションとは、委託のことである。ほう、ふむ、委託か。委託ね(よくわからん)。
  • ネームマングリングとは、擬似プライベートな属性を作ることである。 __X という形式の変数を作ると、それはオートで _{クラス名}__X という変数になるので、名前が重複しない。というのがその効果。
  • 新スタイルクラスとは、スーパークラスに object を指定しないといけない新しいクラスオブジェクトである。意味がぜんぜんわからないが、Python3ではクラスが自動的に新スタイルクラスになっているらしいので気にしなくてもよかろう。
  • ダイアモンド継承とは、継承関係にある2つ以上のクラスが、それぞれで同じクラスをスーパークラスにもっていることである。このとき属性の検索順がちょっとややこしくなる。一番下階層のクラスで属性を検索するとき、その階層で指定したふたつめのスーパークラスよりも先にひとつめのスーパークラスのさらにスーパークラスの属性が検索されるのである。これは、属性の検索が「下から上」が「左から右」よりも優先的に行われることに因っている。ただPython3ではダイアモンド継承の場合検索順序が上記の通りではなくなったとかなんとか…。なんにせよ、属性名をしっかり修飾名で書けば問題なさそうですね。
  • 修飾名とは {インスタンス名}.{属性名} みたいなかたちの名前のことである。

この本への取り組み姿勢は豆知識収集であり、すでに使い慣れている機能について「へーアレは(内部的には)こういうことだったのか」というのを楽しんでいたのだけれど、話がクラスに関連する高度なテクニックに至ってくると、「へーアレはこういうことだったのか」っつーか全部がはじめての学習なのでイチイチ収集していられん。やっぱりクラスはひとつの壁だよ。俺がプログラミングをネットのチュートリアルサイトで始めたときも、単元がクラスに入った瞬間なぜかピタッと理解が止まってしまったからな。の原因は、言うまでもなくオブジェクト指向プログラミングに対する不理解だろう。クラスはオブジェクト指向プログラミングのための道具なので、オブジェクト指向プログラミングがわからなかったらクラスもわからん。今回の読書ではオブジェクト指向プログラミングについてちょっと理解が進んだ気がするのでそれを書いておく。

思うに「オブジェクト指向プログラミング」っていう名前が悪いと思うのだよな。「オブジェクトをガンガン利用するプログラミング」とか「インスタンスをガンガン利用するプログラミング」ならわかる。つまりオブジェクト指向とは「複数の属性を定義したたくさんのクラスを階層化し、必要に応じて属性をカスタマイズしつつ(下位で同名の属性を定義しなおせば上書きとなる)それらを下位クラスで使い回すスタイル」だと言えるんじゃないかなあ。そしてそんなスタイルが有用になるのは大規模なプログラムにおいてのみだ。俺のような初心者はそんなもん作らん。その上Pythonでは数値も文字列もすべてオブジェクトという名前だから、とても分かりづらかったのではなかろうか。「オブジェクト指向もなにも、最初からオブジェクト使いまくっとるやん」ていう。そんなわけで俺の中でオブジェクト指向プログラミングは、「インスタンスをガンガン利用するプログラミング」と言い換えることにしてみる。

言うまでもなく、そのスタイルには以下のようなメリットがある。

  • コードの再利用が可能で手間も物理的な量も節約できる。
  • 実際使うとき触るのは表面のクラスだけでよい(カプセル化)。
  • 変数名の重複が防げる。
  • プログラムのインタフェース、スタイルなどに一貫性が出る。

つまり、これらの項目が必要になったときはじめてクラスの実装を考えればよいんじゃねーかな。いまのままの趣味プログラミングで遊んでる限りは相当先のことになりそうだが。

以下の記事からリンクされています