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<<