一个类继承两个不同的元类(abcmeta和用户定义的元类)

2024-06-16 14:41:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个需要从两个不同的元类继承的class1,这两个元类是Meta1和abc.ABCMeta

当前实施:

Meta1的实现:

class Meta1(type):
    def __new__(cls, classname, parent, attr):
        new_class = type.__new__(cls, classname, parent, attr)
        return super(Meta1, cls).__new__(cls, classname, parent, attr)

Class1摘要的实现

class class1Abstract(object):
    __metaclass__ = Meta1
    __metaclass__ = abc.ABCMeta

mainclass的实现

class mainClass(class1Abstract):
    # do abstract method stuff

我知道两次实现两个不同的元是错误的。

我改变了metclass的加载方式(几次尝试),我得到了这个 TypeError:调用元类基时出错

metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

我没有主意了。。。


EDITED 1

我尝试了这个解决方案,但mainClass不是ClassAbstract的实例

print issubclass(mainClass, class1Abstract) # true
print isinstance(mainClass, class1Abstract) # false

Class1摘要的实现

class TestMeta(Meta1):
    pass


class AbcMeta(object):
    __metaclass__ = abc.ABCMeta
    pass


class CombineMeta(AbcMeta, TestMeta):
    pass


class class1Abstract(object):
    __metaclass__ = CombineMeta

    @abc.abstractmethod
    def do_shared_stuff(self):
        pass

    @abc.abstractmethod
    def test_method(self):
        ''' test method '''

mainClass的实现

class mainClass(class1Abstract):
    def do_shared_stuff(self):
        print issubclass(mainClass, class1Abstract) # True
        print isinstance(mainClass, class1Abstract) # False

由于mainClass继承自抽象类,python应该抱怨mainClass中没有实现test_方法。但它没有任何抱怨,因为print是instance(mainClass,class1 abstract)False

dir(mainClass) 没有

['__abstractmethods__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry']

救命啊!


EDITED 2

Class1摘要的实现

CombineMeta = type("CombineMeta", (abc.ABCMeta, Meta1), {})
class class1Abstract(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def do_shared_stuff(self):
        pass

    @abc.abstractmethod
    def test_method(self):
        ''' test method '''

mainClass的实现

class mainClass(class1Abstract):
    __metaclass__ = CombineMeta
    def do_shared_stuff(self):
        print issubclass(mainClass, class1Abstract) # True
        print isinstance(mainClass, class1Abstract) # False

dir(mainClass)现在有了abstractmethod的神奇方法

['__abstractmethods__', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry', 'do_shared_stuff', 'test_method']

但是python没有警告test_方法没有被实例化

救命啊!


Tags: testselfcachedefdomethodclassmetaclass