gpt4 book ai didi

python - 元类多重继承不一致

转载 作者:IT老高 更新时间:2023-10-28 20:24:10 27 4
gpt4 key购买 nike

为什么会这样:

class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyList(list, MyMixin): pass

好的,按预期工作:

created <class '__main__.MyMixin'>
created <class '__main__.MyList'>

但是这个:

class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyObject(object, MyMixin): pass

不行,就这样炸了?:

created <class '__main__.MyMixin'>
Traceback (most recent call last):
File "/tmp/junk.py", line 11, in <module>
class MyObject(object, MyMixin): pass
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases object, MyMixin

最佳答案

这不是自定义元类问题(尽管它在元类阶段诊断):

>>> class Normal(object): pass
...
>>> class MyObject(object, Normal): pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases object, Normal

问题和这个一样:

>>> class Derived(Normal): pass
...
>>> class Ok(Derived, Normal): pass
...
>>> class Nope(Normal, Derived): pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases Normal, Derived

即,不能从一个基类继承派生类——不可能定义一个满足通常 MRO 约束/保证的一致 MRO。

幸运的是,您不想要这样做——子类可能会覆盖基类的某些方法(这是普通子类的方法;-),并且将基类放在“前面”意味着“掩盖覆盖”。

将基类放在派生类之后是毫无用处的,但至少它是无害的(并且符合正常的 MRO 保证)。

您的第一个示例当然有效,因为 MyMixin 不是 派生自 list:

>>> MyMixin.__mro__
(<class '__main__.MyMixin'>, <type 'object'>)

...但它 派生自 object (就像每个现代风格的 Python 类一样),所以第二个示例无法工作(完全独立于 MyMixin 具有自定义元类)。

关于python - 元类多重继承不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3003053/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com