クラスメソッドと静的メソッド
これまでクラスのメソッドについて説明してきました。クラスが生成したインスタンスオブジェクトが持っているメソッドをインスタンスメソッド(Instans Method) といいます。
Pythonでは、この他に次の2つの種類のメソッドを定義することができます。
クラスメソッド(class Method)
定義するためには、@classmethod でデコレートする必要がある
クラスメソッドは第1引数にクラスを受け取るため、通常cls を記述する。
クラスの状態にアクセスしたり変更することができる
クラス変数へのアクセスや、継承クラスで動作が変わるときに使用する
静的メソッド(Static Method)
定義するためには、@staticmethod でデコレートする必要がある
引数は不要 (与えることができない)
クラスから生成したすべてのインスタンスオブジェクトで共通のオブジェクトになる
クラスの状態にアクセスしたり変更することができない
継承クラスで動作が変わらないときに使用する
code: 0815_class_static_methods.py
class MyClass:
def method(self):
return 'instance method called', self
@classmethod
def classmethod(cls):
return 'class method called', cls
@staticmethod
def staticmethod():
return 'static method called'
print(MyClass.classmethod())
print(MyClass.staticmethod())
print(MyClass.method()) # ERROR
クラスメソッドや静的メソッドはクラスオブジェクトから呼び出せますが、
インスタンスメソッドはクラスオブジェクトから呼び出せません。
これは、インスタンスメソッドはインスタンスオブジェクトにあるメソッドだと考えると理解しやすいでしょう。
静的メソッドは、クラスから生成したすべてのインスタンスオブジェクトで共通のオブジェクトになることを確認してみましょう。
code: 0816_class_static_methods.py
class Queen(object):
def print_vocal():
print("Freddie")
class Whitesnake(object):
@staticmethod
def print_vocal():
print("David")
queen = Queen()
new_queen = Queen()
print(queen.print_vocal)
print(new_queen.print_vocal)
print(Queen.print_vocal)
whitesnake = Whitesnake()
new_whitesnake = Whitesnake()
print(whitesnake.print_vocal)
print(new_whitesnake.print_vocal)
print(Whitesnake.print_vocal)
インスタンスオブジェクトとクラスで定義しているprintNationality のオブジェクトIDが同じなっています。
code: bash
$ python 0816_class_static_methods.py
<bound method Queen.print_vocal of <__main__.Queen object at 0x109e1d470>>
<bound method Queen.print_vocal of <__main__.Queen object at 0x109e1d780>>
<function Queen.print_vocal at 0x109e1f2f0>
<function Whitesnake.print_vocal at 0x109e1f378>
<function Whitesnake.print_vocal at 0x109e1f378>
<function Whitesnake.print_vocal at 0x109e1f378>
クラスメソッドと静的メソッドは、クラス継承がされるときに挙動が明確に違ってきます。
code: 0817_class_static_method_and_class_method.py
class Parent:
val = 'parent class variable'
def __init__(self):
self.val = 'instance variable'
def method(self):
return 'instance method called', self.val
@classmethod
def classmethod(cls):
return 'class method called', cls.val
@staticmethod
def staticmethod():
return 'static method called', Parent.val
class Child(Parent):
val = 'child class variable'
pass
obj = Child()
print( obj.method() )
print( obj.classmethod() )
print( obj.staticmethod() )
これを実行すると次のようになります。
code: bash
$ python 0817_class_static_method_and_class_method.py
('instance method called', 'instance variable')
('class method called', 'child class variable')
('static method called', 'parent class variable')
クラスメソッドは引数にクラスオブジェクトを受け取るため、継承したクラスオブジェクトへのアクセスができます。一方で、静的メソッドは特に引数を持たないので、定義時のクラスオブジェクト(つまり、クラス継承した場合は、親クラス)にしかアクセスできません。
問:
Q1. 1つのファイルに複数のクラスを含めることはできますか?
Q2. 同じクラスから複数のオブジェクトを作成できますか?
Q3. クラスは変数を持つことができますか?
Q4. オブジェクトはクラスを作成できますか?
答えはこの資料の何処かに (^o^)