__metaclass__って何?メモ
Python の __metaclass__ の理解を深めるメモ。
Python 和訳ドキュメント の 3.3.3 クラス生成をカスタマイズする を見てみると、
- そのクラスに対するメタクラスを指定。
- デフォルトは type 。
- 可能性は無限大。
との事。 とりあえず、どのタイミングでメタクラスがクラスを書き換えるのかをテスト。
>>> # メタクラスを定義。
>>> class Meta(type):
... def __new__(cls, name, bases, dicts):
... # 呼び出しタイミングを取る為にprintする。
... print "'__new__' has been called."
... return super(Meta, cls).__new__(cls, name, bases, dicts)
...
>>>
>>> # Metaをメタクラスに持つHigeを定義。
>>> class Hige(object):
... __metaclass__ = Meta
... pass
...
'__new__' has been called. # <--- ココでprintされる。
Python 和訳ドキュメント に書かれてる通り、クラスが生成される前に呼び出されているのが分かる。ここでHigeを継承したクラスも定義してみる。
>>> # Higeを継承したMageを定義。
>>> class Mage(Hige):
... pass
...
'__new__' has been called. # <-- 同じくprintされる。
子クラスにもちゃんと反映されていて、その都度呼び出されている。PHPには無い挙動なので、理解するのにちょっと時間がかかる。
理解を深める為に、 Python 和訳ドキュメント に書かれているインターフェイスチェックとかやってみる。
>>> # メタクラスを定義。
>>> class Meta(type):
... def __new__(cls, name, bases, dicts):
... cls = super(Meta, cls).__new__(cls, name, bases, dicts)
... # saveメソッドを持っているかチェック。
... if not hasattr(cls, 'save'):
... raise AttributeError("'save' is not implemented.")
... return cls
...
>>> # saveメソッドを持たせずにHigeを定義。
>>> class Hige(object):
... __metaclass__ = Meta
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __new__
AttributeError: 'save' is not implemented.
>>>
>>> # 今度はsaveメソッドを持たせてHigeを定義。
>>> class Hige(object):
... __metaclass__ = Meta
... def save(self):
... print 'save!!'
...
>>> # エラーは出ない。
あんまり意味の無いテストなものの、何となく見えてきた気がする。かな? まだ自分で書く事はないものの、分かってないとソースが追いかけれない。
ちょっと実装例を探してみると、 inforno さんの Python:アクセサの生成 を発見。なるほど。こういう事が出来るのか。と納得。
うーむ、 Python は奥が深い。勉強しよ。
- Posted at:
- 2007/09/12 02:30:38
- 0 Comments
- 0 TrackBacks
- Tags:
- Python
- Trackback:
- http://humming.via-kitchen.com/2007/09/12/metaclass-memo/trackback/
TrackBacks
まだ登録されていません。
Comments
まだ登録されていません。