作成前にクラスを検査することはできません。また、一連のステートメントまたはクラス本体の実行が完了するまで、クラスはまだ作成されていません。この情報に初めてアクセスできるMetaClass.__new__
のは、問題のクラスを作成するクラスのメソッド、または問題のクラスを作成するものの実行であり、技術的にはメタクラスまたはクラスである必要はまったくありません (以下の例のように)。
これは非常に大まかなプロトタイプで、おそらくすべてのケースで機能するとは限りませんが、単純なケースでは機能し、おそらくレシピよりも従う方が簡単です。
def meta_class_synthesize(name, bases, attrmap):
seen = set()
seen_add = seen.add
metas = [type(base) for base in bases]
metas = tuple([
meta for meta in metas
if meta is not type and meta not in seen and not seen_add(meta)])
if not metas:
return type(name, bases, attrmap)
elif len(metas) == 1:
return metas[0](name, bases, attrmap)
newmeta_name = "__".join(meta.__name__ for meta in metas)
newmeta = type(newmeta_name, metas, {})
return newmeta(name, bases, attrmap)
class M_A(type):
pass
class M_B(type):
pass
class A:
__metaclass__ = M_A
class B:
__metaclass__ = M_B
class C(A, B):
__metaclass__ = meta_class_synthesize
print type(C) # prints "<class '__main__.M_A__M_B'>"