可能重复:
Why aren't Python's superclass init methods automatically invoked?
例如:
class Pet(object):
def __init__(self, name, species):
self.name = name
self.species = species
def getName(self):
return self.name
def getSpecies(self):
return self.species
def __str__(self):
return "%s is a %s" % (self.name, self.species)
class Dog(Pet):
def __init__(self, name, chases_cats):
Pet.__init__(self, name, "Dog")
self.chases_cats = chases_cats
def chasesCats(self):
return self.chases_cats
如你所见,狗继承了宠物。我完全理解代码。但是为什么我们必须在Dog类中调用init的宠物?为什么不只是把它称为狗类的第一行(类狗(宠物))?它似乎只会创建更混乱的代码。它有点像Python一样杀死了Python的继承点。
答案 0 :(得分:9)
让语言强制超类在之前或之后初始化意味着你失去了功能。子类可能依赖于首先运行超类的初始化,反之亦然。
此外,它无法知道要传递的参数 - 子类决定将哪些值传递给初始值设定项,这为自动传递所有参数提供了更大的灵活性。
初始化超类的另一种方法是使用super,虽然这实际上会动态地初始化self
的超类,通过在对象的__mro__
中查找它(方法解析顺序)
在python 2中:
super(self, Dog).__init__(self, name, "Dog")
在python 3中,您可以进一步减少语法,避免重复自己:
super().__init__(self, name, "Dog")
修改强>:
由于你实际上并没有使用传递给dog的name
参数,你可以通过接受Dog
初始值设定项中的任意关键字和位置参数,并将它们传递给初始化来进一步减少一些语法链:
class Dog(Pet):
def __init__(self, chases_cats, *args, **kwargs):
Pet.__init__(self, *args, species="Dog", **kwargs)
self.chases_cats = chases_cats
class Pet(object):
def __init__(self, name, species, *args, **kwargs):
self.name = name
self.species = species
在您的场景中,初始化程序可能很简单,不需要这个,但知道何时有更多参数和/或更深层次的层次结构是很有用的。
答案 1 :(得分:4)
你可以使物种成为这样的类属性
class Pet(object):
species = None
def __init__(self, name):
self.name = name
def getName(self):
return self.name
def getSpecies(self):
return self.species
def __str__(self):
return "%s is a %s" % (self.name, self.species)
class Dog(Pet):
species = "Dog"
def __init__(self, name, chases_cats):
Pet.__init__(self, name)
self.chases_cats = chases_cats
def chasesCats(self):
return self.chases_cats