关于学习Python的一点学习总结(35->关联超类)

本文探讨了在Python中子类如何调用超类(父类)的构造函数,以避免属性丢失的问题。两种方法被提出:直接调用未关联的超类构造函数,如`Bird.__init__(self)`,以及使用`super()`函数。`super()`函数提供了一种更简洁且在处理多继承时更优雅的方式,自动调用所有必要的超类构造函数。总结了`super`函数的优点,包括简化代码和处理多继承的复杂性。

76.调用为关联的超类(继承的类)构造函数
先举个例子:

 class Bird: 
      def __init__(self): 
        self.hungry = True 
     def eat(self): 
        if self.hungry: 
           print('Aaaah ...') 
           self.hungry = False 
        else: 
           print('No, thanks!')

  class SongBird(Bird): 
     def __init__(self): 
        self.sound = 'Squawk!' 
     def sing(self): 
        print(self.sound)
  输出:>>> b=Bird()
            >>> b.eat()
            Aaaah ...
            >>> b.eat()
            No, thanks!
            >>> sb=SongBird()
            >>> sb.eat()
           Traceback (most recent call last):
              File "<pyshell#84>", line 1, in <module>
               sb.eat()
           File "E:/python/子类.py", line 5, in eat
             if self.hungry:
           AttributeError: 'SongBird' object has no attribute 'hungry'
 可以看到这个sb.eat()报错了,为什么呢?因为在SongBird中重写了构造函数,但新的构造函数没有包含任何初始化属性hungry的代码。我们可以将重写的构造函数去掉试一下:
  class Bird: 
      def __init__(self): 
        self.hungry = True 
      def eat(self): 
        if self.hungry: 
           print('Aaaah ...') 
           self.hungry = False 
        else: 
           print('No, thanks!')


   class SongBird(Bird): 
      def sing(self): 
        print(self.sound)
   输出:>>> b=SongBird()
             >>> b.eat()
             Aaaah ...
            >>> b.eat()
            No, thanks!
      可以看出当去掉重写的构造函数之后,错误没有了,所以要解决这个问题以下有两种方法:

 方法一:就是调用未关联的超类构造函数
  class SongBird(Bird): 
          def __init__(self):
             Bird.__init__(self)
             self.sound = 'Squawk!' 
         def sing(self): 
            print(self.sound)
     输出:>>> sb=SongBird()
               >>> sb.eat()
               Aaaah ...
               >>> sb.eat()
               No, thanks!
 结论:对实例调用方法时,方法的参数self将自动关联到实例;如果通过类调用方法(如:Bird.__init__),就没有实例与其相关联;所以可以随便设置参数self。
 方法二:使用super函数
 class Bird: 
      def __init__(self): 
        self.hungry = True 
      def eat(self): 
        if self.hungry: 
           print('Aaaah ...') 
           self.hungry = False 
        else: 
           print('No, thanks!')


   class SongBird(Bird):
       def __init__(self):
          super().__init__()
          self.sound='Squawk'
      def sing(self): 
          print(self.sound)
    输出:>>> b=SongBird()
              >>> b.sing()
              Squawk
              >>> b.eat()
              Aaaah ...
              >>> b.eat()
              No, thanks!
  调用super函数时,将当前类和当前实例作为参数,对其返回的对象调用方法时,调用的将是超类(而不是当前类)的方法。
super优点
 总结:1.即使有多个超类,也是需要调用函数super一次,但是所有的超类的构造函数也使用super函数;
           2.使用super函数比调用未相关联的构造函数要好的多;
           3.无需关心super返回的是什么(只需要假定返回的是所需要的超类即可);但是事实上返回的是一个super对象,这个对象将负责为你执行方法解析。当访问它的属性时,它将在所有的超类中查找,直到找到指定的超类的属性或者报错。
          4.相对于旧式类,如果两个超类从同一个类派生出来,在使用新式类和函数super时将自动得到处理(而且无需知道super工作原理)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值