1
from abc import ABCMeta
class test1(object):
    __metaclass__ = ABCMeta 
    def test1(self):
        print 'test1'
    
class UpperAttrMetaclass(type):
    def __new__(cls, name, bases, dct={}):
        a = super(UpperAttrMetaclass, cls).__new__(cls, name, bases, dct)
        return a
    
b = UpperAttrMetaclass('hehe',(test1,),{})()

会报错如下:TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

如果将test1中的__metaclass__ = ABCMeta去掉就能运行。但是不想去掉,如何在以上基础上解决呢?(程序是在运行时动态决定继承哪些类,继承的类名和数量都不一定)

2016-01-30 提问

1 个回答

3

已采纳

针对这个代码解释错误信息:“B的metaclass必须是所有B的父类(这里只有test1)的metaclass的子类(但不一定要求是直接子类)”。

从字面上理解就可以找到解决办法:

class bMetaClass(ABCMeta, UpperAttrMetaclass):
    pass

b = bMetaClass('hehe', (test1,), {})()
1
回复 六月的夜曲

Python源码里添加这个限制的地方没有说明具体原因,我猜可能是因为多个metaclass的行为可能会冲突(比如UpperClass和LowerClass,还有可能是这些metaclass的顺序也可能导致不同的结果),加上这个限制可以让开发者去思考可能存在的问题。

felix021 · 2016年01月30日

展开评论

推广链接