まず参考サイトから。 - "Python のクラスシステム" -- http://www.shido.info/py/python7.html - "Python のクラスメソッド – デコレータ @classmethod, @staticmethod を使って" -- http://jutememo.blogspot.com/2008/09/python-classmethod-staticmethod.html - "クラスの挙動まとめ #1" -- http://d.hatena.ne.jp/hope-echoes/20080409/1207732499 - "クラスの挙動まとめ #2" -- http://d.hatena.ne.jp/hope-echoes/20080410/1207826778 大変参考になりました。これらの記事を書かれた皆さん、ありがとうございます。 なんというか・・・非常に簡潔な作り。C++とかJavaというよりは、JavaScriptとかPerlに近い。個人的な感覚ではPerlに似てるなぁ、と思う。Perlはリファレンスに対してパッケージでblessするという書いててもよく分からないんだけどとにかくそんなことをしてるんだけど、Pythonの場合は名前空間に対してClass名をbindするという感じで、多少の階層や概念の齟齬はあれど感覚的にはよく似てると思った。 だから、逆に言えば隠蔽機能は皆無に近いみたい。やろうとするとPerlと同じ感じで、特殊メソッドを使ってかなりガリガリマジックを駆使する必要が有るっぽい。簡潔な作りは簡潔に利用する方がいい気がする。せっかく覚えることを減らしてくれてるんだから。 Pythonドキュメントで言えば、Win版2.5でのCHMヘルプの章立てで示すと以下の辺りが参考になる。 - "Library Reference" -> "2. Build-in Objects" -- dir(), property(), classmethod(), staticmethod(), type() あたりが興味深い。 - "Library Reference" -> "3. Build-in Types" -> "3.12 Special Attributes" -- __dict__, __class__, __bases__, __name__ というオブジェクトの特殊属性の解説。 - "Library Reference" -> "5. Data Types" -> "5.16 new" -- インスタンス生成の為のローレベル関数。コア。 - "Language Reference" -> "3. Data model" -> "3.2 The standard type hierarchy" -- "Callable Types"の"User-defined functions"と"User-defined methods"は重要。前掲の「クラスの挙動のまとめ #2」の「メソッドオブジェクト」項と併せて読むと理解が深まる。 - "Language Reference" -> "3. Data model" -> "3.4 Special method names" -- __init__や__new__など、拡張の為の特殊メソッド名の解説。 あと、結局 __init__() とかインスタンスメソッドの第一引数で使う"self"という奴、予約語というわけじゃないのだから、"this"とかにしてもOKじゃね?と思ったら本当にOKだった。 >>> class C1(object): ... v1 = 'abc' ... def m1(this): print "Hello, " + this.v1 ... >>> o1 = C1() >>> o1.m1() Hello, abc ちなみに以下のような実験で、どうやらインスタンス生成ではクラスオブジェクトの名前空間(__dict__)がコピーされてインスタンスの名前空間に引き継がれているようではあるが、未調査なので何とも言えない。 >>> class C1(object): ... v1 = 'abc' ... def m1(self): print 'Hello, ', self.v1 ... >>> o1 = C1() >>> o1.m1() Hello, abc >>> o1.v1 = 'ABC' >>> C1.v1 'abc' >>> o1.m1() Hello, ABC >>> o2 = C1() >>> o2.m1() Hello, abc >>> C1.v1 = 'DEF' >>> o3 = C1() >>> o3.m1() Hello, DEF >>> o1.m1() Hello, ABC o1オブジェクトのv1属性を書き換えても、C1(クラス)オブジェクトのv1属性は変わっていない。このため、o2で新たにインスタンスを生成しても、最初の"abc"が引き継がれている。一方、C1オブジェクト側でv1属性を変更した後o3でインスタンスを生成すると、変更された値が引き継がれている。当然、o1のv1属性は先に変更した値のままである。