无法解决与子类的元类的冲突

时间:2018-04-02 01:43:48

标签: python python-3.x

我需要一个同一个类的静态实例和一个我认为使用元类的解决方案。

我有以下word.py

from .token import Token
from .tag import Tag

class Token:
    def __init__(self, tag_id):
        self.tag = tag_id

    def __str__(self):
        return str(self.tag)

class MetaWord(type):

    def __init__(cls, clsname, superclasses, attributedict):
        cls.and_ = cls('&&', Tag.AND)
        cls.or_ = cls("||", Tag.OR)
        cls.eq = cls("==", Tag.EQ)
        cls.ne = cls("!=", Tag.NE)     


class Word(Token, metaclass=MetaWord):

    def __init__(self, lexeme, tag):
        super(self.__class__, self).__init__(tag)
        self.lexeme = lexeme

和另一个文件type.py文件,其Type类继承自Word

from lexer.word import Word
from lexer.tag import Tag


class MetaType(type):
    def __init__(cls, clsname, superclasses, attributedict):
        cls.int_ = cls('int', Tag.BASIC, 4)
        cls.float_ = cls('float', Tag.BASIC, 8)
        cls.char_ = cls('char', Tag.BASIC, 1)
        cls.bool_ = cls('bool', Tag.BASIC, 1)


class Type(Word, metaclass=MetaType):
    def __init__(self, word, tag_id, w):
        super(self.__class__, self).__init__(word, tag_id)
        self.width = w

我遇到的问题是每次导入Type时都会出现错误:

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

我已经阅读了有关此问题的一些主题,但尚未弄清楚如何解决元类之间的冲突

1 个答案:

答案 0 :(得分:2)

如果您希望代码以您组织的方式工作,则必须使MetaType成为MetaWord的子类。当Python试图实例化你的Type类时,它会查看MRO并看到Type有元类MetaType和基类Word,但类Word有元类MetaWord。这引发了冲突,因为Python没有办法解决Type似乎有两个元类,MetaWord和MetaType,它们彼此无关。

以下代码是我认为您的问题的最小复制品:

class Meta1(type):
    pass

class Class1(metaclass=Meta1):
    pass

class Meta2(type):
    pass

class Class2(Class1, metaclass=Meta2):
    pass

此代码会产生与您相同的错误。将Meta2的定义更改为:

class Meta2(Meta1):
    pass

解决了这个问题。