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

我看不到这两种情况之间的区别。

IljaEverilä

传递给type的字典sdct包括,根据此PEP,这reprstr现在使用的字典__qualname__

尝试添加

print(Child is Child.sibling)  # False
print(Child.sibling.__name__)  # "ChildSibling"

您会发现它确实是兄弟姐妹。

至于sibling().x抛出的原因已经包含了相同的sdctChild.__init__,它最终以__init__动态创建的new type结束ChildSibling在调用期间sibling()super()将类解析为,Child为其提供了的实例ChildSibling

还要注意,除零参数形式外,super()不限于在内部方法中使用。两个参数形式准确地指定了参数并进行了适当的引用。零参数形式仅在类定义内起作用,因为编译器会填充必要的详细信息以正确检索要定义的类,以及为常规方法访问当前实例。

https://docs.python.org/3/library/functions.html#super

通过将第一个参数传递给方法作为实例来完成对当前实例的访问。

super() -> same as super(__class__, <first argument>)

Object / typeobject.c的第7210行引发错误

尝试使用以下方法消除__init__的错误__new__

del sdct['__init__']

现在

print(Child().sibling().x)

将打印3。

解决“泛型”继承和元编程更友好的方法__init__是使用以下2个参数形式super()

def __init__(self):
    super(self.__class__, self).__init__()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章