为什么是这样:
class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyList(list, MyMixin): pass
Run Code Online (Sandbox Code Playgroud)
好的,按预期工作:
created <class '__main__.MyMixin'>
created <class '__main__.MyList'>
Run Code Online (Sandbox Code Playgroud)
但是这个:
class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyObject(object, MyMixin): pass
Run Code Online (Sandbox Code Playgroud)
不行,并且如此爆炸?:
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
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 83
它不是自定义元类问题(虽然它是在元类阶段诊断出来的):
>>> 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
Run Code Online (Sandbox Code Playgroud)
问题和这个问题一样:
>>> 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
Run Code Online (Sandbox Code Playgroud)
即,不能从基类继承乘以派生类 - 不可能定义满足通常的MRO约束/保证的一致MRO.
幸运的是,您不希望这样做 - 子类可能会覆盖基类的某些方法(这是正常的子类所做的 ;-),并且基类"在前面"将意味着"遮蔽覆盖".
将基类放在派生类之后是没用的,但至少它是无害的(并且与正常的MRO保证一致).
你的第一个例子当然是有效的,因为MyMixin
它不是来自list
:
>>> MyMixin.__mro__
(<class '__main__.MyMixin'>, <type 'object'>)
Run Code Online (Sandbox Code Playgroud)
...但它是源自object
(像每一个现代风格的Python类),所以第二个例子不能(从完全独立工作,MyMixin
有一个自定义的元类).
归档时间: |
|
查看次数: |
17755 次 |
最近记录: |