Acuisition
Acquisitionのtest.pyを読んでみました。
Acquisitionは、オブジェクトの属性を、その環境から取得するためのメカニズム。継承に似てるけど、継承の階層をトラバースするんじゃなくて、包含関係をトラバースする。
下の例のように、ExtensionClass.Baseをmix-inすると、サブクラスでacquisitionの機能が使えるようになる。
>>> import ExtensionClass, Acquisition >>> class C(ExtensionClass.Base): ... color='red' >>> class A(Acquisition.Implicit): ... def report(self): ... print self.color >>> a = A() >>> c = C() >>> c.a = a >>> c.a.report() red >>> d = C() >>> d.color = 'green' >>> d.a = a >>> d.a.report() green >>> a.report() # raises an attribute error Traceback (most recent call last): ... AttributeError: color
クラスAは、Acquisition.Implicitからacquisitionの機能を継承している。オブジェクトaは、cやdを介してアクセスしてるときはcolor属性を持っているけど、それ自体にはcolor属性を持っていない。aは、その環境からcolor属性を取得している。
Acquisition wrapper
acquisitionをサポートするオブジェクトがExtensionClassのインスタンスを介してアクセスされると、Acquisition wrapperと呼ばれる特殊なオブジェクトが返される。例えば上の例では c.a は、c と a に対する参照を含むラッパ−を返す。このラッパーは、aで属性が見つからなければ、cの属性を検索する。
acquisitionラッパーには、ラップされたオブジェクトにアクセスするための、'aq_parent', 'aq_self', 'aq_base'という属性がある。
例えば、上の例では次の式と
>>> c.a.aq_parent is c 1
そして、この式は
>>> c.a.aq_self is a 1
両方ともtrueに評価される。しかし、この式は
>>> c.a is a 0
falseになる。c.aは、cとaのラッパーであって、a自体ではない。
aq_baseは、aq_selfと同じようなものであるが、ラッパーはネストしていることがあるので、aq_selfが返すオブジェクトは、ラッパーであることがある。aq_baseは、すべてのラッパーを取除いて、その下にあるオブジェクトを指している。
続きはまた今度。