メタクラスで奮闘中
まず、
class Base(type): def __new__(cls, clsname, clsbases, clsdict): parents = [b for b in clsbases if isinstance(b,Base)] print parents return super(cls, Base).__new__(cls, clsname, clsbases, clsdict) class Child(object): __metaclass__ = Base class GrandChild(Child): pass
とすると、Child生成時にはparentsは空だがGrandChild生成時にはparentsは空ではない。
parents = [b for b in clsbases if isinstance(b,Base)]
となっているのでclsbasesにBaseないしそれを継承した何かのインスタンスが存在しなければparentsは空のはずだが、GrandChild生成時には何故だかBaseを継承しているわけではないChildがparentsに入る。
ChildのインスタンスはBaseを継承していないのでisinstance(Child(),Base)は偽を返すがChild自体はメタクラスとしてBaseを使っているからかisinstance(Child,Base)は真を返す。
しかしながら
class Base(object): def __new__(cls, clsname, clsbases, clsdict): parents = [b for b in clsbases if isinstance(b,Base)] print parents return type(clsname, clsbases, clsdict)
と変えると、isinstance(Child,Base)も偽になる。
調べると"__new__"のドキュメンテーション文字列に
T.__new__(S, ...) -> a new object with type S, a subtype of T
とある。だから
super(cls, Base).__new__(cls, clsname, clsbases, clsdict)
で生成した場合、生成されたクラスはclsのサブタイプとなるようだ。
うん、よく分からない。書いてみたら分かるかとも思ったがまだダメだ。もうちょっと調べるか。