関数・クラス(2)

クラスとインスタンス

クラス、インスタンスは一般的なオブジェクト指向言語と同じ考え方(クラスは設計図であり、
インスタンスはそれを元に生成された個々の製品である、のような)で取り扱うことが出来る。

クラス定義

Python でクラスを定義するときの構文は以下の通り。

class クラス名(基本クラス):
    定義

基本クラスは省略可能だが、特別に指定したいクラスが無い場合には
クラス object を指定することが推奨されている。
「定義」の部分ではメソッドやクラスのアトリビュートを定義する。

メソッド

クラスのメソッドは C++ のクラスのメンバ関数に相当する。クラスのメソッドの定義は
通常の関数とほぼ同じだが、引数リストの先頭に特殊な引数 self を追加する必要がある。
self は C++ の this ポインタのようなもので、クラスメソッドに暗黙に渡され、
インスタンスごとのアトリビュートを保持する。

class Foo(object):
    def __init__(self, x):
        self.x = x
    def echo(self):
        print self.x

f = Foo(0)    # Foo.__init__ が呼び出される
f.echo()
0

上記のように、実際にクラスのメソッドを呼び出す場合には self を渡す必要はない。
上記のコードのクラス Foo のクラスメソッド __init__ は C++ のコンストラクタのように
インスタンスが生成されるときに呼び出される。

インスタンスアトリビュート

インスタンスアトリビュート(属性)は C++ のクラスのメンバ変数に近い。
しかし、前節のコードの __init__ に見られるように宣言は必要なく、
*1を渡すことで自動的に生成される。
また、後から任意にアトリビュートを追加することができる。

class Foo(object):
    def __init__(self, x):
        self.x = x
    
    def echo(self):
        print self.x, self.y

f = Foo(0)
# ここで f.echo を呼び出すとエラー
f.y = "abc"    # 合法
f.echo()
0 abc

ただしバグの元となるのでインスタンスの外側からアトリビュートを追加することは避けたほうが良い。

クラスのアトリビュート

クラス定義の、メソッド定義ではない場所で定義されたアトリビュート
クラスに属するアトリビュートとなる( C++ のクラスの static メンバ変数に近い)。
このアトリビュートにはクラス名.アトリビュートでアクセスすることが出来る。
C++ の static メンバ変数と違い、クラスのメソッド内からアクセスする場合にも
クラス名を省略することは出来ない

class Foo(object):
    value=0
    def echo(self):
        print Foo.value    # Foo. を省略するとエラー

*1:実際にはオブジェクトの参照