クラス(class)
Pythonの世界は、整数などの単純な値も含め、すべての値はobjectクラスを継承したクラスのインスタンスでできています。
1 2 3 4 5 6 7 8 | >>> type(1) <type 'int'> >>> isinstance(1, object) True >>> type("hage") <type 'str'> >>> isinstance("hage", object) True |
classを定義する
もちろん自分でclassを定義することできます。soundメソッドを持つDuckクラスとCatクラスを定義してみます。
1 2 3 4 5 6 7 | >>> class Duck: ... def sound(self): ... print 'quack' ... >>> class Cat: ... def sound(self): ... print 'myaa' |
定義したクラスを使う
型名の後ろに()をつけて呼び出すと、インスタンスが生成されます。メソッドを呼び出すときは、引数selfを省略します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> duck = Duck() >>> duck.sound() quack >>> cat = Cat() >>> cat.sound() myaa >>> def kick(animal): ... animal.sound() ... >>> kick(duck) quack >>> kick(cat) myaa |
kick関数は、引数としてanimalをとりますが、型は指定されていません。pythonは動的型付言語なので、型チェックは実行時まで行われないのです。
インスタンスメソッドとクラスメソッド
Pythonのクラスには、インスタンスメソッドとクラスメソッドの2種類メソッドを定義できる。
インスタンスメソッド
先ほど定義したDuckクラスやCatクラスのsound()メソッドは、インスタンスメソッドです。インスタンスを生成すれば呼び出せますが、クラスに対しては呼び出せません。
1 2 3 4 5 6 7 | >>> Duck().sound() quack >>> Duck.sound() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unbound method sound() must be called with Duck instance as first arg ument (got nothing instead) |
クラスメソッド
クラスメソッドを定義するには、デコレータ(@で始まる部分のこと)を使うのが手っ取り早い。第1引数にクラスオブジェクトが渡される。本来は違う書き方していたらしいが、いまさら覚える必要はないと思う。
1 2 3 4 5 6 7 8 9 | >>> class Duck: ... @classmethod ... def kind(cls): ... print "Duck" ... print cls ... >>> Duck.kind() Duck __main__.Duck |
インスタンス変数とクラス変数
Pythonのクラスには、インスタンス変数とクラス変数という2種類の値が存在する。クラス変数は、クラスに対して一意な値であり、インスタンス変数はインスタンスごとに存在する値である。
インスタンス変数
インスタンス変数は、selfに対して設定する。初期値設定は__init__関数で行う。インスタンスごとに独立した値を持つ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | >>> class SeparatedCounter: ... def __init__(self): ... self.count = 0 ... def next(self): ... self.count = self.count + 1 ... return self.count ... >>> sc1 = SeparatedCounter() >>> sc2 = SeparatedCounter() >>> sc1.next() 1 >>> sc1.next() 2 >>> sc2.next() 1 >>> sc2.next() 2 >>> sc1.next() 3 |
クラス変数
クラス変数はcls(クラスメソッドの第1引数)に対して指定する。初期値はクラス内で直接指定する。クラス変数はインスタンスからでもアクセスできる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | >>> class Counter: ... count = 0 ... @classmethod ... def next(cls): ... cls.count = cls.count + 1 ... return cls.count ... >>> Counter.next() 1 >>> Counter.next() 2 >>> Counter.next() 3 >>> c1 = Counter() >>> c2 = Counter() >>> c1.next() 4 >>> c2.next() 5 >>> Counter.next() 6 |