我有一个像这样的基类:
class Token:
def __init__(self, value):
self.value = value.strip()
self.tokens = None
def get_value(self):
return self.value
def tokenize(self):
pass # abstract stub
def __str__(self):
return type(self).__name__ + ': '+ re.sub(r'\s+', ' ', self.value)
还有很多孩子的课程:
class T_DefineDirective(Token):
def __init__(self, value):
super().__init__(value)
class T_IncludeDirective(Token):
def __init__(self, value):
super().__init__(value)
class T_IfdefDirective(Token):
def __init__(self, value):
super().__init__(value)
class T_Identifier(Token):
def __init__(self, value):
super().__init__(value)
class T_Rvalue(Token):
def __init__(self, value):
super().__init__(value)
def tokenize(self):
pass # stuff here
现在我是一名干性程序员。我讨厌重复。如果您查看代码,__init__
部分将被复制粘贴到所有子类中。
我的问题是,有没有办法避免重复,或者这是否真的是正确的方法?
(请注意,示例有点缩短,因此可能没有多大意义。但您可以看到我的意思)。
答案 0 :(得分:2)
如果您在Token
子类中没有任何其他设置工作要做,则可以安全地不覆盖__init__
。
如果你必须执行一些特定于子类的初始化,那么你正在使用的模式很好并且是“pythonic”#。
澄清:
__init__
,那么Python将使用在其父类(其中一个)上定义的__init__
方法,如果可能的话
__init__
__new__
;然后将新创建的对象传递给__init__
进行初始化答案 1 :(得分:1)
如果你真的想要消除尽可能多的样板:
首先,如果所有内容都是__init__
,则您不需要super()
;正如sapi的回答所解释的那样,特殊方法就像任何其他方法一样被继承。
其次,您可以动态创建一堆类:
token_classes = {
'T_{}'.format(name): type('T_{}'.format(name), (Token,), {})
for name in 'DefineDirective IncludeDirective IfdefDirective Identifier'.split()
}
你可以直接在dict中使用它们,但是如果你真的想把它们变成全局变量你可以:
globals().update(token_classes)
然而,避免重复的整个目标是使您的代码更具可读性和可维护性,在这种情况下,我认为我们正在实现相反的目标。 :)