从子类__init __()中初始化父类是否可以接受?

时间:2014-10-21 05:41:42

标签: python inheritance subclass

从子类中初始化父类是否是一种好习惯,以便父类属性可用于创建的子类实例? 这样做有替代方案或最佳做法吗?

举个例子:

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。

从子类实例访问父属性和方法的正确方法是什么?我误解了子类的使用吗?

3 个答案:

答案 0 :(得分:2)

不仅可以接受,你几乎总是应该调用父类的构造函数。你不会这样做的唯一原因是你

  1. 绝对相信在父类中定义的任何初始化代码都不会是对象运行所必需的
  2. 您希望显式覆盖父类的初始化行为。
  3. 对于新的样式类(从对象继承的类),最好使用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!"