pythonの__metaclass__について

いつもクラスデコレータの方を使ってmetaclassをあまり使っていなかったので情報を整理。

metaクラスで定義する__new__について

class FooMeta(type):
    def __new__(cls, name, bases, attrs):
        print "cls:%s" % cls
        print "name:%s" % name
        print "bases:%s" % bases
        print "attrs:%s" % attrs
        return super(FooMeta, cls).__new__(cls, name, bases, attrs)	


class Foo(object):
    __metaclass__ = FooMeta

    def __init__(self):
        self.foo = "foo"

    message = "--hello, this is Foo class--"

    @classmethod
    def koo(cls):
        print cls

    def foo(self):
        print self.foo

#Fooが定義された後に、__metaclass__に渡したFooMetaの__new__が実行される。
実行結果
cls:<class '__main__.FooMeta'>
name:Foo
bases:<type 'object'>
attrs:{'__module__': '__main__', 'foo': <function foo at 0x1eeb488>, '__metaclass__': <class '__main__.FooMeta'>, 'koo': <classmethod object at 0x1ef04e8>, '__init__': <function __init__ at 0x1eeb398>}

__new__()の引数の意味。

  名前 意味(入っている値)
cls metaclass自体
name __metaclass__を利用したクラスの名前 Foo
bases metaclassの祖先
attrs __metaclass__を利用したクラスの持つメソッド {...}

メッセージのやりとりで何が入るのか確認

Barでmessageを格納して、__new__でそれを呼び出す。
BarMetaは使われたクラスにresponseを格納。

class BarMeta(type):
    def __new__(cls, name, bases, attrs):
        if "message" in attrs:
            print attrs["message"]

        attrs["response"] = ">>hi,  this is BarMeta class<<"
        return super(BarMeta, cls).__new__(cls, name, bases, attrs)


class Bar(object):
    message = "--hello,  this is Bar class"
    __metaclass__ = BarMeta

bar = Bar()
print "---"
print bar.response

##
# --hello,  this is Bar class
# ---
# >>hi,  this is BarMeta class<<