class MyMeta(type):
def __new__(meta, cls, bases, attributes):
print 'MyMeta.__new__'
return type.__new__(meta, cls, bases, attributes)
def __init__(clsobj, cls, bases, attributes):
print 'MyMeta.__init__'
class MyClass(object):
__metaclass__ = MyMeta
foo = 'bar'
同じ結果を達成する別の方法:
cls = "MyClass"
bases = ()
attributes = {'foo': 'bar'}
MyClass = MyMeta(cls, bases, attributes)
MyMeta
は呼び出し可能であるため、Pythonは特別なメソッドを使用します__call__
。
Pythonはのタイプ(この場合は)を検索__call__
しますMyMeta
type
「新しいスタイルのクラスの場合、特別なメソッドの暗黙的な呼び出しは、オブジェクトのインスタンスディクショナリではなく、オブジェクトのタイプで定義されている場合にのみ正しく機能することが保証されます。」
MyClass = MyMeta(...)
次のように解釈されます:
my_meta_type = type(MyMeta)
MyClass = my_meta_type.__call__(MyMeta, cls, bases, attributes)
私の中には次のtype.__call__()
ようなものを想像します:
MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
meta_class = MyClass.__metaclass__
meta_class.__init__(MyClass, cls, bases, attributes)
return MyClass
MyMeta.__new__()
MyClass
の構築方法を決定します:
type.__new__(meta, cls, bases, attributes)
の正しいメタクラス(はMyMeta
)を設定しますMyClass
type(cls, bases, attributes)
のデフォルトのメタクラス(タイプ)を設定しますMyClass