从子类中初始化父类是否是一种好习惯,以便父类属性可用于创建的子类实例? 这样做有替代方案或最佳做法吗?
举个例子:
class Animal(object):
def __init__(self, name, weight, cute=False, image=None):
#Instantiation attributes
self.name = name
self.weight = weight
self.cute = cute
self.image = image
#Attributes common to all animals
self.extinct = False
def get_animal_stats(self):
print arbitrary_animal_stat
class Dog(Animal):
def __init__(self, name, weight):
Animal.__init__(self, name, weight, cute=True, image="dog.com")
#Additional attributes unique to dogs
self.number_legs = 4
self.teeth = True
def make_noise(self):
print "Bark!"
据我所知,在子类初始化期间没有初始化父类,子类对象只能访问自己的属性(即。number_legs和teeth,和make_noise)而不是父类属性或方法(即灭绝)和get_animal_stats)。
我发现自己为预定义的对象编写了许多小类,但必须用子进程初始化父类。通过这种方式,我可以动态创建一个简单的Animal,或者通过Dog子类创建一个更具描述性的Animal。
从子类实例访问父属性和方法的正确方法是什么?我误解了子类的使用吗?
答案 0 :(得分:2)
不仅可以接受,你几乎总是应该调用父类的构造函数。你不会这样做的唯一原因是你
对于新的样式类(从对象继承的类),最好使用super()
,因为它在多重继承的情况下处理分辨率顺序。在Python 2.7中,使用:
class ParentFooA(GrandparentFoo):
def __init__(self):
some_important_initialization_code()
class ChildFoo(ParentFoo):
def __init__(self):
super(ChildFoo, self).__init__()
请注意,另一个不错的属性是,当您定义继承时(例如,在行中),除了之外,您不必在ParentFoo
中的任何位置使用名称ChildFoo
class ChildFoo(...)
)。它也适用于其他方法:
class ChildFoo(ParentFoo):
...
def do_buzz(self):
super(ChildFoo, self).do_buzz()
super()
不适用于旧式类(即不从object
继承的类)。
这意味着对于大部分标准库,您仍然必须显式调用父类的构造函数。所以在这种情况下:
class OldStyleParent:
def __init__(self):
...
您必须在OldStyleParent.__init__()
明确致电__init__()
。
在Python 3中,super
的语法很简单:
class ChildFooInPython3(ParentFoo):
def __init__(self):
super().__init__()
答案 1 :(得分:1)
没错,虽然你可能想使用super():
super(Dog, self).__init__...
或者在Python 3中:
super().__init__...
答案 2 :(得分:-1)
class Dog(Animal):
def __init__(self, name, weight):
super(Dog, self).__init__(name, weight, cute=True, image="dog.com")
#Additional attributes unique to dogs
self.number_legs = 4
self.teeth = True
def make_noise(self):
print "Bark!"