メタクラスについて
メタクラスを作るには、typeオブジェクトを使用します。
通常はオブジェクトタイプを判別するために使用するこのオブジェクト、typeはメタクラス(クラス・オブジェクトを生成するクラス)です。
メタクラスなので、クラスを生成することも可能なら、typeを継承することで、カスタムメタクラスを作ることもできます。
type(‘クラス名’, (スーパークラスのタプル), {属性の辞書})
使い方は、typeを継承したクラスを別のクラスの__metaclass__属性に入れておきます。
class Hoge(type):
pass
class Sam:
__metaclass__ = Hoge
メタクラスとは、クラスオブジェクトのクラス、すなわち「クラスのクラス」。
正式には、あるオブジェクトがあると、そのクラスのクラスがメタクラス、ということになります。
def Hoge(self):
print('Hello, World!')
sam = type('MyClass',
(object,),
{'myMethod': greet})
if __name__ == '__main__':
obj = sam() #▼表示
obj.myMethod() #---Hello, World!---
print(obj.__class__) #---<class '__main__.MyClass'>---
print(type(obj)) #---<class '__main__.MyClass'>---
print(obj.__class__.__class__) #---<type 'type'>---
obj.__class__.__class__ が になっているので type が「クラスのクラス」すなわちメタクラスであるということがわかります。
クラス自身がオブジェクトである言語でなければ、メタクラスは存在しません。
メタクラスは、普段は隠れているので、意識せずともプログラムは全然問題なく書けます。
無名クラス
hoge = type('C',(),{'x':100, 'y':lambda self:print('Hello')})
a = hoge()
print(a.x) #---100を表示---
print(c.y()) #---Helloを表示---
上記のようにclass文を使わずにクラスを作り、グローバル空間に名前を残さずに無名関数ならぬ無名クラスを作成することができます。
つまり class 文は組み込み関数 type のシンタックスシュガーで、内部的には組み込み関数 type が呼び出されているようにイメージします。
カスタムメタクラスの作成
クラスを生成するメタクラスを作るには、typeオブジェクトを継承すれば良いです。
そして、クラスにメタクラスを適用するには、クラスの中で__metaclass__属性にメタクラスを指定します。
class クラス名 (親クラス, metaclass = メタクラス名, メタクラスの引数名 = 引数値)
class Meta(type): #メタクラスである type を継承して
pass
#---python2系-------
class Hoge:
__metaclass__ = Hoge
#---python3系-------
class Hoge(metaclass = Meta):
pass