私はやや奇妙なメタクラスの質問があります。私は別のスーパークラスから継承し、元のクラスの属性としてそれを割り当てる '兄弟'クラスを動的に作成するためにメタクラスを使用しています。以下は、最小限の設定です:pythonメタクラスの継承問題
class Meta(type):
def __new__(cls, name, parents, dct):
sdct = dct.copy()
dct['sibling'] = type(name+'Sibling', (Mom,), sdct)
return super().__new__(cls, name, (Dad,), dct)
class Mom:
def __init__(self):
self.x = 3
class Dad:
def __init__(self):
self.x = 4
class Child(metaclass=Meta):
def __init__(self):
super().__init__()
self.y = 1 # <<< added from feedback
print(Child().x) # 4
print(Child().sibling) # <class '__main__.Child'> | should be ChildSibling
print(Child().sibling().x) # should be 3 instead throws:
# TypeError: super(type, obj): obj must be an instance or subtype of type
print(Child().sibling().y) # should print 4
何かが「兄弟」クラスの作成に上記の間違っているように見えるが、私は何をかなりよく分かりません。たとえば、これがうまくいくことがわかります:
class ChildAbstract:
def __init__(self):
super().__init__()
ChildSibling = type('ChildSibling', (ChildAbstract, Mom), {})
Child = type('Child', (ChildAbstract, Dad), {'sibling': ChildSibling})
print(Child().sibling().x) # 3
私は2つのケースの違いは分かりません。
興味深いポイント:
ソリューションは、「汎用」の継承と
__init__
友好メタプログラミングはsuper()
の2引数形式を使用することです子プロセスでは何もしないでください.____ init__これは問題をかなり解決していません(説明するために更新されたコード)。 – Buckああ、上のノートではこれを説明しています – Buck
@Buck 2つ目の例が動作する理由は、2つの動的タイプの基底に 'ChildAbstract'が含まれていて、' super() 'が満足しているということです。 –