クラスについて

クラス定義とインスタンスの作成

class Test:
    pass

何もしないクラスを定義しています。


クラス名を関数のように呼び出して、インスタンスを作ります。

t = Test()
print t
#=> <__main__.Test instance at 0x009AD3A0>

インスタンスメソッド

class Test:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def p(self):
        print "x = %s" % self.x
        print "y = %s" % self.y

__init__() というメソッドを定義すると、インスタンスを作成する時に呼ばれます。いわゆるコンストラクタというやつで、変数の初期化などはここで行います。
また、インスタンスメソッドは一番目の引数に自分自身(インスタンス)を受け取ります。そしてメソッド内では、このインスタンスを使って変数にアクセスします。


メソッド定義では一番目の引数はインスタンスになっていますが、自動的に渡されるので、引数にインスタンスを渡す必要はありません。

t = Test(5, 5)
t.p()
x = 5
y = 5

インスタンス変数へのアクセス

t = Test(5, 5)

print t.x
#=> 5

print t.y
#=> 5


定義されていないインスタンス変数にアクセスしてみます。

print t.z
#=> AttributeError: Test instance has no attribute 'z'

定義されていないインスタンス変数を参照しようとするとエラーになります。


では、定義されていないインスタンス変数に値を代入してみます。

t.z = 5
print t.z
#=> 5

今度はエラーにはなりません。これは未定義のインスタンス変数に値を代入すると、その変数が新たに定義されるからです。

プライベート変数

Pythonでは外部からのインスタンス変数へのアクセスを完全に防ぐことはできません。代わりに変数名をアンダーバーを二つ並べたもので始めることで、そのまま名前で外部からアクセスすることを防ぐことができます。

class Test:
    def __init__(self, x=0, y=0):
        self.x = __x
        self.y = __y

    def p(self):
        print "x = %s" % self.__x
        print "y = %s" % self.__y


外部からインスタンス変数にアクセスしてみます。

print x.__x
#=> AttributeError: Test instance has no attribute '__x'

エラーになります。


どうしても、__x の値を参照したい場合は以下のようにします。

print t._Test__x
#=> 5

つまり変数名をアンダーバーで始めると、外部からは _クラス名を付けないとアクセスできないようになるわけです。

クラス変数

クラス定義が最後まで実行されると、クラスオブジェクトが作られます。クラスオブジェクトに属する変数がクラス変数です。

class Test:
    format = "Hello, %s."

    def hello(self, name):
        print Test.format % name

クラス定義の中で変数を定義すれば、それがクラス変数になります。


クラス変数にはクラス名.変数名でアクセスします。ちなみにクラス名はクラスオブジェクトへの参照です。

print Test.format
#=> "Hello, %s."

t = Test()
t.hello("yukiue")
#=> "Hello, yukiue."


インスタンスからでもクラス変数を参照することはできますが、同名のインスタンス変数がある場合は、そちらが優先されます。

print t.format
#=> "Hello, %s."

t.format = "hoge"
print t.format
#=> "hoge"