初めてのPython(24章前編)
class ステートメント
def ステートメントと同じような動き
- 該当モジュールが読み込まれた時に実行される
- クラス名に指定したクラスオブジェクトを生成し、クラス名の変数に代入する
クラスは名前空間として考えられる
[kobakoba0723@fedora13-intel64 ~]$ cat sample.py #!/usr/bin/env python class C1(object): data = "spam" def setdata(self, value): self.data = value def printdata(self): print "data: ", self.data if __name__ == '__main__': x = C1() y = C1() print '(x.data, y.data, C1.data) = (%s, %s, %s)' % (x.data, y.data, C1.data) C1.data = "egg" print '(x.data, y.data, C1.data) = (%s, %s, %s)' % (x.data, y.data, C1.data) x.setdata("onion") print '(x.data, y.data, C1.data) = (%s, %s, %s)' % (x.data, y.data, C1.data) [kobakoba0723@fedora13-intel64 ~]$ python sample.py (x.data, y.data, C1.data) = (spam, spam, spam) (x.data, y.data, C1.data) = (egg, egg, egg) (x.data, y.data, C1.data) = (onion, egg, egg) [kobakoba0723@fedora13-intel64 ~]$
クラスメソッド
基本的には通常の関数オブジェクトと同じ
大きな違いは、『呼び出される時に第1引数にインスタンスオブジェクトを必ず受け取る』こと
そのため、メソッドの呼び出しに使うインスタンス.メソッド(引数...)は、自動的に以下に読み換えられる。
クラス.メソッド(インスタンス, 引数...)
[kobakoba0723@fedora13-intel64 ~]$ python Python 2.6.4 (r264:75706, Apr 1 2010, 02:55:51) [GCC 4.4.3 20100226 (Red Hat 4.4.3-8)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sample >>> x = sample.C1() >>> x.setdata("onion") >>> x.printdata() data: onion >>> sample.C1.setdata(x, "carrot") >>> sample.C1.printdata(x) data: carrot >>>
スーパークラスの__init__呼び出し
クラス.メソッド(インスタンス, 引数...)の構文を使うことで、スーパークラスの初期化処理をサブクラスから呼び出すことが出来る。
サブクラスの中で、スーパークラスの属性を利用する必要があって、初期化処理をしたい時に使う
[kobakoba0723@fedora13-intel64 ~]$ cat sample.py #!/usr/bin/env python class C1(object): def __init__(self, value): self.x = value class C2(C1): def __init__(self, value_x, value_y): self.y = value_y C1.__init__(self, value_x) def printdata(self): print "(x, y) = (%d, %d)" % (self.x, self.y) if __name__ == '__main__': a = C2(1, 2) a.printdata() [kobakoba0723@fedora13-intel64 ~]$ python sample.py (x, y) = (1, 2) [kobakoba0723@fedora13-intel64 ~]$
抽象クラス
クラスの機能の一部をサブクラスに依存するクラスのこと
以下の場合のC1が抽象クラス
[kobakoba0723@fedora13-intel64 ~]$ cat abstract.py #!/usr/bin/env python class C1(object): def method(self): print 'in C1.method' self.abstract() def abstract(self): assert 0, 'abstract must be defined' class C2(C1): def abstract(self): print 'in C2.abstract' class C3(C1): pass if __name__ == '__main__': x = C2() x.method() y = C3() y.method() [kobakoba0723@fedora13-intel64 ~]$ python abstract.py in C1.method in C2.abstract in C1.method Traceback (most recent call last): File "abstract.py", line 23, in <module> y.method() File "abstract.py", line 6, in method self.abstract() File "abstract.py", line 9, in abstract assert 0, 'abstract must be defined' AssertionError: abstract must be defined [kobakoba0723@fedora13-intel64 ~]$
C1のabstractメソッドにassertステートメントを使うことで、サブクラスでabstractメソッドを定義しないとエラーを起こすことが出来る。
raiseステートメントでも同様のことは可能で、C1.abstractメソッドは以下のようになる。
def abstract(self): raise NameError, 'abstract must be defined'