当使用继承另一个元类的元类时,子类的super().__ init __()失败

时间:2018-04-02 21:24:50

标签: python python-3.x

我有三个类,TokenWordType,用于在Python 3中编写的一个小编译器,我作为CS课程的一部分。我的目标是建立一个静态变量,指向WordType中相同类的实例。

为了实现它,我正在尝试使用元类。如下:

from lexer.tag import Tag

class MetaWord(type):
    def __init__(cls, name, bases, attrs, **kwargs):
        cls.and_ = cls('&&', Tag.AND)
        cls.or_ = cls("||", Tag.OR)     


class MetaType(MetaWord):
    def __init__(cls, name, bases, attrs, **kwargs):
        cls.int_ = cls('int', Tag.BASIC, 4)
        cls.float_ = cls('float', Tag.BASIC, 8)


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


class Word(Token, metaclass=MetaWord):
    def __init__(self, lexeme, tag_id):
        super(self.__class__, self).__init__(tag_id)
        self.lexeme = lexeme


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

运行Word类它可以正常工作,但当我尝试实例化Type类时,在行中:

cls.int_ = cls('int', Tag.BASIC, 4)

我得到:{TypeError}:__init__() missing 1 required positional argument: 'tag_id'

调试,我发现__init__类的Word方法中出现错误:

super(self.__class__, self).__init__(tag_id)

如果我在__init__中没有任何参数的情况下调用上述行,我会得到:

{TypeError}:__init__() missing 2 required positional argument: 'lexeme' and 'tag_id'

如果我传递这两个参数,例如:

super(self.__class__, self).__init__('int', tag_id)

我又来了:

{TypeError}:__init__() missing 1 required positional argument: 'tag_id'

如果我尝试传递Type的所有3个参数:

super(self.__class__, self).__init__('int', tag_id, 4)

我明白了:

{TypeError}__init__() takes 3 positional arguments but 4 were given

我无法理解这种行为,似乎该类无法找到Token类的 init ()方法,或者__init__()元类的方法正在破坏某些东西。我该如何解决?

1 个答案:

答案 0 :(得分:0)

正如评论所建议的那样,解决方案确实是在没有参数的情况下调用super()

问题在于,当我从super()删除参数时,我收到了错误

RuntimeError: super(): empty __class__ cell

经过一些研究,我发现这个错误是python 3中的一个错误,那就是fixed in version 3.6

将我的python版本更新为3.6修复了问题。