初始化

  • 当在Python中出现继承的情况时,一定要注意初始化函数init的行为:
    • 如果子类没有定义自己的初始化函数,父类的初始化函数会被默认调用;但是如果要实例化子类的对象,则只能传入父类的初始化函数对应的参数,否则会出错。
    • 如果子类定义了自己的初始化函数,而在子类中没有显示调用父类的初始化函数,则父类的属性不会被初始化
    • 如果子类定义了自己的初始化函数,在子类中显示调用父类,子类和父类的属性都会被初始化

子类没有定义自己的初始化函数,父类的初始化函数会被默认调用:

  1. # 定义父类:Parent
  2. class Parent(object):
  3. def __init__(self, name):
  4. self.name = name
  5. print("create an instance of:", self.__class__.__name__)
  6. print("name attribute is:", self.name)
  7. # 定义子类Child ,继承父类Parent
  8. class Child(Parent):
  9. pass
  10. # 子类实例化时,由于子类没有初始化,此时父类的初始化函数就会默认被调用
  11. # 且必须传入父类的参数 name
  12. c = Child("init Child")
  • 子类实例化时,由于子类没有初始化,此时父类的初始化函数就会默认被调用,此时传入父类的参数name,输出结果为(没有传入父类name参数的输出结果会报错:):
  1. create an instance of: Child
  2. name attribute is: init Child
  3. ## (没有传入父类name参数的输出结果会报错)
  4. Traceback (most recent call last):
  5. File "xxx.py", line 40, in <module>
  6. c = Child()
  7. TypeError: __init__() missing 1 required positional argument: 'name'

子类定义了自己的初始化函数,而在子类中没有显示调用父类的初始化函数,则父类的属性不会被初始化

  1. class Parent(object):
  2. def __init__(self, name):
  3. self.name = name
  4. print("create an instance of:", self.__class__.__name__)
  5. print("name attribute is:", self.name)
  6. # 子类继承父类
  7. class Child(Parent):
  8. # 子类中没有显示调用父类的初始化函数
  9. def __init__(self):
  10. print("call __init__ from Child class")
  11. # c = Child("init Child")
  12. # print()
  13. # 将子类实例化
  14. c = Child()
  15. print(c.name)

在子类中没有显示调用父类的初始化函数,则父类的属性不会被初始化,因而此时调用子类中name 属性不存在:

  1. Traceback (most recent call last):
  2. File "xxx.py", line 57, in <module>
  3. print(c.name)
  4. AttributeError: 'Child' object has no attribute 'name'

如果子类定义了自己的初始化函数,显示调用父类,子类和父类的属性都会被初始化

  1. class Parent(object):
  2. def __init__(self, name):
  3. self.name = name
  4. print("create an instance of:", self.__class__.__name__)
  5. print("name attribute is:", self.name)
  6. class Child(Parent):
  7. def __init__(self):
  8. print("call __init__ from Child class")
  9. super(Child,self).__init__("data from Child") # 要将子类 Child 和 self 传递进去
  10. # c = Child("init Child")
  11. # print()
  12. d = Parent('tom')
  13. c = Child()
  14. print(c.name)

子类定义了自己的初始化函数,显示调用父类,子类和父类的属性都会被初始化的输出结果:

  1. # 实例化父类Parent的结果
  2. create an instance of: Parent
  3. name attribute is: tom
  4. # 实例化子类Child的结果
  5. call __init__ from Child class
  6. # super 首先会先使得父类初始化的参数进行实例化
  7. create an instance of: Child
  8. name attribute is: data from Child
  9. data from Child