我有三个类,Token
,Word
和Type
,用于在Python 3中编写的一个小编译器,我作为CS课程的一部分。我的目标是建立一个静态变量,指向Word
和Type
中相同类的实例。
为了实现它,我正在尝试使用元类。如下:
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__()
元类的方法正在破坏某些东西。我该如何解决?
答案 0 :(得分:0)
正如评论所建议的那样,解决方案确实是在没有参数的情况下调用super()
。
问题在于,当我从super()
删除参数时,我收到了错误
RuntimeError: super(): empty __class__ cell
经过一些研究,我发现这个错误是python 3中的一个错误,那就是fixed in version 3.6
将我的python版本更新为3.6修复了问题。